@gcoredev/fastedge-test 0.2.1 → 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.
@@ -1 +1 @@
1
- {"fastedge_run_version": "v0.16.5"}
1
+ {"fastedge_run_version": "v0.16.7"}
Binary file
@@ -927,7 +927,13 @@ var HostFunctions = class {
927
927
  pendingHttpCall = null;
928
928
  httpCallResponse = null;
929
929
  streamClosed = false;
930
- // Local response state (from proxy_send_local_response / send_http_response)
930
+ // Local response state (from proxy_send_local_response / send_http_response).
931
+ // `headers` carries the additional headers passed as the 4th argument of
932
+ // `send_http_response`; ProxyWasmRunner merges these into finalResponse at
933
+ // the short-circuit points so they reach the caller alongside any headers
934
+ // accumulated via stream_context.headers.response.add() in the same hook.
935
+ // Stored as tuples to preserve order and duplicate-name semantics (e.g. for
936
+ // multi-value Set-Cookie additions).
931
937
  localResponse = null;
932
938
  // FastEdge extensions
933
939
  secretStore;
@@ -1277,12 +1283,13 @@ var HostFunctions = class {
1277
1283
  );
1278
1284
  const statusText = this.memory.readString(statusCodePtr, statusCodeLen);
1279
1285
  const body = this.memory.readBytes(bodyPtr, bodyLen);
1286
+ let headers = [];
1280
1287
  if (headerPairsLen > 0) {
1281
1288
  const headerBytes = this.memory.readBytes(headerPairsPtr, headerPairsLen);
1282
- const headers = HeaderManager.deserializeBinary(headerBytes);
1283
- this.logDebug(`send_local_response headers (not merged): ${JSON.stringify(headers)}`);
1289
+ headers = HeaderManager.deserializeBinaryToTuples(headerBytes);
1290
+ this.logDebug(`send_local_response headers: ${JSON.stringify(headers)}`);
1284
1291
  }
1285
- this.localResponse = { statusCode, statusText, body };
1292
+ this.localResponse = { statusCode, statusText, body, headers };
1286
1293
  this.logs.push({
1287
1294
  level: 1,
1288
1295
  message: `local_response status=${statusCode} ${statusText} bodyLen=${body.byteLength} grpc=${grpcStatus}`
@@ -2076,14 +2083,15 @@ var ProxyWasmRunner = class {
2076
2083
  const local = this.hostFunctions.getLocalResponse();
2077
2084
  const responseHeaders2 = results.onRequestHeaders.output.response.headers;
2078
2085
  this.hostFunctions.resetLocalResponse();
2079
- const contentType2 = HeaderManager.firstValue(responseHeaders2["content-type"]) || "text/plain";
2086
+ const mergedHeaders = local.headers.length > 0 ? HeaderManager.appendMerge(responseHeaders2, HeaderManager.tuplesToRecord(local.headers)) : responseHeaders2;
2087
+ const contentType2 = HeaderManager.firstValue(mergedHeaders["content-type"]) || "text/plain";
2080
2088
  const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
2081
2089
  return {
2082
2090
  hookResults: results,
2083
2091
  finalResponse: {
2084
2092
  status: local.statusCode,
2085
2093
  statusText: local.statusText,
2086
- headers: responseHeaders2,
2094
+ headers: mergedHeaders,
2087
2095
  body,
2088
2096
  contentType: contentType2,
2089
2097
  isBase64: isBase642
@@ -2119,14 +2127,15 @@ var ProxyWasmRunner = class {
2119
2127
  const local = this.hostFunctions.getLocalResponse();
2120
2128
  const responseHeaders2 = results.onRequestBody.output.response.headers;
2121
2129
  this.hostFunctions.resetLocalResponse();
2122
- const contentType2 = HeaderManager.firstValue(responseHeaders2["content-type"]) || "text/plain";
2130
+ const mergedHeaders = local.headers.length > 0 ? HeaderManager.appendMerge(responseHeaders2, HeaderManager.tuplesToRecord(local.headers)) : responseHeaders2;
2131
+ const contentType2 = HeaderManager.firstValue(mergedHeaders["content-type"]) || "text/plain";
2123
2132
  const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
2124
2133
  return {
2125
2134
  hookResults: results,
2126
2135
  finalResponse: {
2127
2136
  status: local.statusCode,
2128
2137
  statusText: local.statusText,
2129
- headers: responseHeaders2,
2138
+ headers: mergedHeaders,
2130
2139
  body,
2131
2140
  contentType: contentType2,
2132
2141
  isBase64: isBase642
@@ -2296,16 +2305,17 @@ var ProxyWasmRunner = class {
2296
2305
  }
2297
2306
  if (results.onResponseHeaders.returnCode === 1 && this.hostFunctions.hasLocalResponse()) {
2298
2307
  const local = this.hostFunctions.getLocalResponse();
2299
- const headers = results.onResponseHeaders.output.response.headers;
2308
+ const responseHeaders2 = results.onResponseHeaders.output.response.headers;
2300
2309
  this.hostFunctions.resetLocalResponse();
2301
- const contentType2 = HeaderManager.firstValue(headers["content-type"]) || "text/plain";
2310
+ const mergedHeaders = local.headers.length > 0 ? HeaderManager.appendMerge(responseHeaders2, HeaderManager.tuplesToRecord(local.headers)) : responseHeaders2;
2311
+ const contentType2 = HeaderManager.firstValue(mergedHeaders["content-type"]) || "text/plain";
2302
2312
  const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
2303
2313
  return {
2304
2314
  hookResults: results,
2305
2315
  finalResponse: {
2306
2316
  status: local.statusCode,
2307
2317
  statusText: local.statusText,
2308
- headers,
2318
+ headers: mergedHeaders,
2309
2319
  body,
2310
2320
  contentType: contentType2,
2311
2321
  isBase64: isBase642
@@ -2339,16 +2349,17 @@ var ProxyWasmRunner = class {
2339
2349
  }
2340
2350
  if (results.onResponseBody.returnCode === 1 && this.hostFunctions.hasLocalResponse()) {
2341
2351
  const local = this.hostFunctions.getLocalResponse();
2342
- const headers = results.onResponseBody.output.response.headers;
2352
+ const responseHeaders2 = results.onResponseBody.output.response.headers;
2343
2353
  this.hostFunctions.resetLocalResponse();
2344
- const contentType2 = HeaderManager.firstValue(headers["content-type"]) || "text/plain";
2354
+ const mergedHeaders = local.headers.length > 0 ? HeaderManager.appendMerge(responseHeaders2, HeaderManager.tuplesToRecord(local.headers)) : responseHeaders2;
2355
+ const contentType2 = HeaderManager.firstValue(mergedHeaders["content-type"]) || "text/plain";
2345
2356
  const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
2346
2357
  return {
2347
2358
  hookResults: results,
2348
2359
  finalResponse: {
2349
2360
  status: local.statusCode,
2350
2361
  statusText: local.statusText,
2351
- headers,
2362
+ headers: mergedHeaders,
2352
2363
  body,
2353
2364
  contentType: contentType2,
2354
2365
  isBase64: isBase642
@@ -2723,7 +2734,9 @@ var ProxyWasmRunner = class {
2723
2734
  }
2724
2735
  }
2725
2736
  createImports() {
2726
- const wasi = new import_node_wasi.WASI({ version: "preview1", env: this.dictionary.getAll() });
2737
+ const dictEnv = this.dictionary.getAll();
2738
+ const wasiEnv = Object.keys(dictEnv).length === 0 ? { __FASTEDGE_RUNNER__: "1" } : dictEnv;
2739
+ const wasi = new import_node_wasi.WASI({ version: "preview1", env: wasiEnv });
2727
2740
  const wasiImport = wasi.wasiImport;
2728
2741
  return {
2729
2742
  env: this.hostFunctions.createImports(),
package/dist/lib/index.js CHANGED
@@ -883,7 +883,13 @@ var HostFunctions = class {
883
883
  pendingHttpCall = null;
884
884
  httpCallResponse = null;
885
885
  streamClosed = false;
886
- // Local response state (from proxy_send_local_response / send_http_response)
886
+ // Local response state (from proxy_send_local_response / send_http_response).
887
+ // `headers` carries the additional headers passed as the 4th argument of
888
+ // `send_http_response`; ProxyWasmRunner merges these into finalResponse at
889
+ // the short-circuit points so they reach the caller alongside any headers
890
+ // accumulated via stream_context.headers.response.add() in the same hook.
891
+ // Stored as tuples to preserve order and duplicate-name semantics (e.g. for
892
+ // multi-value Set-Cookie additions).
887
893
  localResponse = null;
888
894
  // FastEdge extensions
889
895
  secretStore;
@@ -1233,12 +1239,13 @@ var HostFunctions = class {
1233
1239
  );
1234
1240
  const statusText = this.memory.readString(statusCodePtr, statusCodeLen);
1235
1241
  const body = this.memory.readBytes(bodyPtr, bodyLen);
1242
+ let headers = [];
1236
1243
  if (headerPairsLen > 0) {
1237
1244
  const headerBytes = this.memory.readBytes(headerPairsPtr, headerPairsLen);
1238
- const headers = HeaderManager.deserializeBinary(headerBytes);
1239
- this.logDebug(`send_local_response headers (not merged): ${JSON.stringify(headers)}`);
1245
+ headers = HeaderManager.deserializeBinaryToTuples(headerBytes);
1246
+ this.logDebug(`send_local_response headers: ${JSON.stringify(headers)}`);
1240
1247
  }
1241
- this.localResponse = { statusCode, statusText, body };
1248
+ this.localResponse = { statusCode, statusText, body, headers };
1242
1249
  this.logs.push({
1243
1250
  level: 1,
1244
1251
  message: `local_response status=${statusCode} ${statusText} bodyLen=${body.byteLength} grpc=${grpcStatus}`
@@ -2032,14 +2039,15 @@ var ProxyWasmRunner = class {
2032
2039
  const local = this.hostFunctions.getLocalResponse();
2033
2040
  const responseHeaders2 = results.onRequestHeaders.output.response.headers;
2034
2041
  this.hostFunctions.resetLocalResponse();
2035
- const contentType2 = HeaderManager.firstValue(responseHeaders2["content-type"]) || "text/plain";
2042
+ const mergedHeaders = local.headers.length > 0 ? HeaderManager.appendMerge(responseHeaders2, HeaderManager.tuplesToRecord(local.headers)) : responseHeaders2;
2043
+ const contentType2 = HeaderManager.firstValue(mergedHeaders["content-type"]) || "text/plain";
2036
2044
  const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
2037
2045
  return {
2038
2046
  hookResults: results,
2039
2047
  finalResponse: {
2040
2048
  status: local.statusCode,
2041
2049
  statusText: local.statusText,
2042
- headers: responseHeaders2,
2050
+ headers: mergedHeaders,
2043
2051
  body,
2044
2052
  contentType: contentType2,
2045
2053
  isBase64: isBase642
@@ -2075,14 +2083,15 @@ var ProxyWasmRunner = class {
2075
2083
  const local = this.hostFunctions.getLocalResponse();
2076
2084
  const responseHeaders2 = results.onRequestBody.output.response.headers;
2077
2085
  this.hostFunctions.resetLocalResponse();
2078
- const contentType2 = HeaderManager.firstValue(responseHeaders2["content-type"]) || "text/plain";
2086
+ const mergedHeaders = local.headers.length > 0 ? HeaderManager.appendMerge(responseHeaders2, HeaderManager.tuplesToRecord(local.headers)) : responseHeaders2;
2087
+ const contentType2 = HeaderManager.firstValue(mergedHeaders["content-type"]) || "text/plain";
2079
2088
  const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
2080
2089
  return {
2081
2090
  hookResults: results,
2082
2091
  finalResponse: {
2083
2092
  status: local.statusCode,
2084
2093
  statusText: local.statusText,
2085
- headers: responseHeaders2,
2094
+ headers: mergedHeaders,
2086
2095
  body,
2087
2096
  contentType: contentType2,
2088
2097
  isBase64: isBase642
@@ -2252,16 +2261,17 @@ var ProxyWasmRunner = class {
2252
2261
  }
2253
2262
  if (results.onResponseHeaders.returnCode === 1 && this.hostFunctions.hasLocalResponse()) {
2254
2263
  const local = this.hostFunctions.getLocalResponse();
2255
- const headers = results.onResponseHeaders.output.response.headers;
2264
+ const responseHeaders2 = results.onResponseHeaders.output.response.headers;
2256
2265
  this.hostFunctions.resetLocalResponse();
2257
- const contentType2 = HeaderManager.firstValue(headers["content-type"]) || "text/plain";
2266
+ const mergedHeaders = local.headers.length > 0 ? HeaderManager.appendMerge(responseHeaders2, HeaderManager.tuplesToRecord(local.headers)) : responseHeaders2;
2267
+ const contentType2 = HeaderManager.firstValue(mergedHeaders["content-type"]) || "text/plain";
2258
2268
  const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
2259
2269
  return {
2260
2270
  hookResults: results,
2261
2271
  finalResponse: {
2262
2272
  status: local.statusCode,
2263
2273
  statusText: local.statusText,
2264
- headers,
2274
+ headers: mergedHeaders,
2265
2275
  body,
2266
2276
  contentType: contentType2,
2267
2277
  isBase64: isBase642
@@ -2295,16 +2305,17 @@ var ProxyWasmRunner = class {
2295
2305
  }
2296
2306
  if (results.onResponseBody.returnCode === 1 && this.hostFunctions.hasLocalResponse()) {
2297
2307
  const local = this.hostFunctions.getLocalResponse();
2298
- const headers = results.onResponseBody.output.response.headers;
2308
+ const responseHeaders2 = results.onResponseBody.output.response.headers;
2299
2309
  this.hostFunctions.resetLocalResponse();
2300
- const contentType2 = HeaderManager.firstValue(headers["content-type"]) || "text/plain";
2310
+ const mergedHeaders = local.headers.length > 0 ? HeaderManager.appendMerge(responseHeaders2, HeaderManager.tuplesToRecord(local.headers)) : responseHeaders2;
2311
+ const contentType2 = HeaderManager.firstValue(mergedHeaders["content-type"]) || "text/plain";
2301
2312
  const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
2302
2313
  return {
2303
2314
  hookResults: results,
2304
2315
  finalResponse: {
2305
2316
  status: local.statusCode,
2306
2317
  statusText: local.statusText,
2307
- headers,
2318
+ headers: mergedHeaders,
2308
2319
  body,
2309
2320
  contentType: contentType2,
2310
2321
  isBase64: isBase642
@@ -2679,7 +2690,9 @@ var ProxyWasmRunner = class {
2679
2690
  }
2680
2691
  }
2681
2692
  createImports() {
2682
- const wasi = new WASI({ version: "preview1", env: this.dictionary.getAll() });
2693
+ const dictEnv = this.dictionary.getAll();
2694
+ const wasiEnv = Object.keys(dictEnv).length === 0 ? { __FASTEDGE_RUNNER__: "1" } : dictEnv;
2695
+ const wasi = new WASI({ version: "preview1", env: wasiEnv });
2683
2696
  const wasiImport = wasi.wasiImport;
2684
2697
  return {
2685
2698
  env: this.hostFunctions.createImports(),
@@ -59,6 +59,7 @@ export declare class HostFunctions {
59
59
  statusCode: number;
60
60
  statusText: string;
61
61
  body: Uint8Array;
62
+ headers: HeaderTuples;
62
63
  } | null;
63
64
  resetLocalResponse(): void;
64
65
  getRequestHeaders(): HeaderRecord;
@@ -19324,7 +19324,13 @@ var HostFunctions = class {
19324
19324
  pendingHttpCall = null;
19325
19325
  httpCallResponse = null;
19326
19326
  streamClosed = false;
19327
- // Local response state (from proxy_send_local_response / send_http_response)
19327
+ // Local response state (from proxy_send_local_response / send_http_response).
19328
+ // `headers` carries the additional headers passed as the 4th argument of
19329
+ // `send_http_response`; ProxyWasmRunner merges these into finalResponse at
19330
+ // the short-circuit points so they reach the caller alongside any headers
19331
+ // accumulated via stream_context.headers.response.add() in the same hook.
19332
+ // Stored as tuples to preserve order and duplicate-name semantics (e.g. for
19333
+ // multi-value Set-Cookie additions).
19328
19334
  localResponse = null;
19329
19335
  // FastEdge extensions
19330
19336
  secretStore;
@@ -19674,12 +19680,13 @@ var HostFunctions = class {
19674
19680
  );
19675
19681
  const statusText = this.memory.readString(statusCodePtr, statusCodeLen);
19676
19682
  const body = this.memory.readBytes(bodyPtr, bodyLen);
19683
+ let headers = [];
19677
19684
  if (headerPairsLen > 0) {
19678
19685
  const headerBytes = this.memory.readBytes(headerPairsPtr, headerPairsLen);
19679
- const headers = HeaderManager.deserializeBinary(headerBytes);
19680
- this.logDebug(`send_local_response headers (not merged): ${JSON.stringify(headers)}`);
19686
+ headers = HeaderManager.deserializeBinaryToTuples(headerBytes);
19687
+ this.logDebug(`send_local_response headers: ${JSON.stringify(headers)}`);
19681
19688
  }
19682
- this.localResponse = { statusCode, statusText, body };
19689
+ this.localResponse = { statusCode, statusText, body, headers };
19683
19690
  this.logs.push({
19684
19691
  level: 1,
19685
19692
  message: `local_response status=${statusCode} ${statusText} bodyLen=${body.byteLength} grpc=${grpcStatus}`
@@ -20473,14 +20480,15 @@ var ProxyWasmRunner = class {
20473
20480
  const local = this.hostFunctions.getLocalResponse();
20474
20481
  const responseHeaders2 = results.onRequestHeaders.output.response.headers;
20475
20482
  this.hostFunctions.resetLocalResponse();
20476
- const contentType2 = HeaderManager.firstValue(responseHeaders2["content-type"]) || "text/plain";
20483
+ const mergedHeaders = local.headers.length > 0 ? HeaderManager.appendMerge(responseHeaders2, HeaderManager.tuplesToRecord(local.headers)) : responseHeaders2;
20484
+ const contentType2 = HeaderManager.firstValue(mergedHeaders["content-type"]) || "text/plain";
20477
20485
  const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
20478
20486
  return {
20479
20487
  hookResults: results,
20480
20488
  finalResponse: {
20481
20489
  status: local.statusCode,
20482
20490
  statusText: local.statusText,
20483
- headers: responseHeaders2,
20491
+ headers: mergedHeaders,
20484
20492
  body,
20485
20493
  contentType: contentType2,
20486
20494
  isBase64: isBase642
@@ -20516,14 +20524,15 @@ var ProxyWasmRunner = class {
20516
20524
  const local = this.hostFunctions.getLocalResponse();
20517
20525
  const responseHeaders2 = results.onRequestBody.output.response.headers;
20518
20526
  this.hostFunctions.resetLocalResponse();
20519
- const contentType2 = HeaderManager.firstValue(responseHeaders2["content-type"]) || "text/plain";
20527
+ const mergedHeaders = local.headers.length > 0 ? HeaderManager.appendMerge(responseHeaders2, HeaderManager.tuplesToRecord(local.headers)) : responseHeaders2;
20528
+ const contentType2 = HeaderManager.firstValue(mergedHeaders["content-type"]) || "text/plain";
20520
20529
  const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
20521
20530
  return {
20522
20531
  hookResults: results,
20523
20532
  finalResponse: {
20524
20533
  status: local.statusCode,
20525
20534
  statusText: local.statusText,
20526
- headers: responseHeaders2,
20535
+ headers: mergedHeaders,
20527
20536
  body,
20528
20537
  contentType: contentType2,
20529
20538
  isBase64: isBase642
@@ -20693,16 +20702,17 @@ var ProxyWasmRunner = class {
20693
20702
  }
20694
20703
  if (results.onResponseHeaders.returnCode === 1 && this.hostFunctions.hasLocalResponse()) {
20695
20704
  const local = this.hostFunctions.getLocalResponse();
20696
- const headers = results.onResponseHeaders.output.response.headers;
20705
+ const responseHeaders2 = results.onResponseHeaders.output.response.headers;
20697
20706
  this.hostFunctions.resetLocalResponse();
20698
- const contentType2 = HeaderManager.firstValue(headers["content-type"]) || "text/plain";
20707
+ const mergedHeaders = local.headers.length > 0 ? HeaderManager.appendMerge(responseHeaders2, HeaderManager.tuplesToRecord(local.headers)) : responseHeaders2;
20708
+ const contentType2 = HeaderManager.firstValue(mergedHeaders["content-type"]) || "text/plain";
20699
20709
  const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
20700
20710
  return {
20701
20711
  hookResults: results,
20702
20712
  finalResponse: {
20703
20713
  status: local.statusCode,
20704
20714
  statusText: local.statusText,
20705
- headers,
20715
+ headers: mergedHeaders,
20706
20716
  body,
20707
20717
  contentType: contentType2,
20708
20718
  isBase64: isBase642
@@ -20736,16 +20746,17 @@ var ProxyWasmRunner = class {
20736
20746
  }
20737
20747
  if (results.onResponseBody.returnCode === 1 && this.hostFunctions.hasLocalResponse()) {
20738
20748
  const local = this.hostFunctions.getLocalResponse();
20739
- const headers = results.onResponseBody.output.response.headers;
20749
+ const responseHeaders2 = results.onResponseBody.output.response.headers;
20740
20750
  this.hostFunctions.resetLocalResponse();
20741
- const contentType2 = HeaderManager.firstValue(headers["content-type"]) || "text/plain";
20751
+ const mergedHeaders = local.headers.length > 0 ? HeaderManager.appendMerge(responseHeaders2, HeaderManager.tuplesToRecord(local.headers)) : responseHeaders2;
20752
+ const contentType2 = HeaderManager.firstValue(mergedHeaders["content-type"]) || "text/plain";
20742
20753
  const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
20743
20754
  return {
20744
20755
  hookResults: results,
20745
20756
  finalResponse: {
20746
20757
  status: local.statusCode,
20747
20758
  statusText: local.statusText,
20748
- headers,
20759
+ headers: mergedHeaders,
20749
20760
  body,
20750
20761
  contentType: contentType2,
20751
20762
  isBase64: isBase642
@@ -21120,7 +21131,9 @@ var ProxyWasmRunner = class {
21120
21131
  }
21121
21132
  }
21122
21133
  createImports() {
21123
- const wasi = new import_node_wasi.WASI({ version: "preview1", env: this.dictionary.getAll() });
21134
+ const dictEnv = this.dictionary.getAll();
21135
+ const wasiEnv = Object.keys(dictEnv).length === 0 ? { __FASTEDGE_RUNNER__: "1" } : dictEnv;
21136
+ const wasi = new import_node_wasi.WASI({ version: "preview1", env: wasiEnv });
21124
21137
  const wasiImport = wasi.wasiImport;
21125
21138
  return {
21126
21139
  env: this.hostFunctions.createImports(),
@@ -19288,7 +19288,13 @@ var HostFunctions = class {
19288
19288
  pendingHttpCall = null;
19289
19289
  httpCallResponse = null;
19290
19290
  streamClosed = false;
19291
- // Local response state (from proxy_send_local_response / send_http_response)
19291
+ // Local response state (from proxy_send_local_response / send_http_response).
19292
+ // `headers` carries the additional headers passed as the 4th argument of
19293
+ // `send_http_response`; ProxyWasmRunner merges these into finalResponse at
19294
+ // the short-circuit points so they reach the caller alongside any headers
19295
+ // accumulated via stream_context.headers.response.add() in the same hook.
19296
+ // Stored as tuples to preserve order and duplicate-name semantics (e.g. for
19297
+ // multi-value Set-Cookie additions).
19292
19298
  localResponse = null;
19293
19299
  // FastEdge extensions
19294
19300
  secretStore;
@@ -19638,12 +19644,13 @@ var HostFunctions = class {
19638
19644
  );
19639
19645
  const statusText = this.memory.readString(statusCodePtr, statusCodeLen);
19640
19646
  const body = this.memory.readBytes(bodyPtr, bodyLen);
19647
+ let headers = [];
19641
19648
  if (headerPairsLen > 0) {
19642
19649
  const headerBytes = this.memory.readBytes(headerPairsPtr, headerPairsLen);
19643
- const headers = HeaderManager.deserializeBinary(headerBytes);
19644
- this.logDebug(`send_local_response headers (not merged): ${JSON.stringify(headers)}`);
19650
+ headers = HeaderManager.deserializeBinaryToTuples(headerBytes);
19651
+ this.logDebug(`send_local_response headers: ${JSON.stringify(headers)}`);
19645
19652
  }
19646
- this.localResponse = { statusCode, statusText, body };
19653
+ this.localResponse = { statusCode, statusText, body, headers };
19647
19654
  this.logs.push({
19648
19655
  level: 1,
19649
19656
  message: `local_response status=${statusCode} ${statusText} bodyLen=${body.byteLength} grpc=${grpcStatus}`
@@ -20437,14 +20444,15 @@ var ProxyWasmRunner = class {
20437
20444
  const local = this.hostFunctions.getLocalResponse();
20438
20445
  const responseHeaders2 = results.onRequestHeaders.output.response.headers;
20439
20446
  this.hostFunctions.resetLocalResponse();
20440
- const contentType2 = HeaderManager.firstValue(responseHeaders2["content-type"]) || "text/plain";
20447
+ const mergedHeaders = local.headers.length > 0 ? HeaderManager.appendMerge(responseHeaders2, HeaderManager.tuplesToRecord(local.headers)) : responseHeaders2;
20448
+ const contentType2 = HeaderManager.firstValue(mergedHeaders["content-type"]) || "text/plain";
20441
20449
  const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
20442
20450
  return {
20443
20451
  hookResults: results,
20444
20452
  finalResponse: {
20445
20453
  status: local.statusCode,
20446
20454
  statusText: local.statusText,
20447
- headers: responseHeaders2,
20455
+ headers: mergedHeaders,
20448
20456
  body,
20449
20457
  contentType: contentType2,
20450
20458
  isBase64: isBase642
@@ -20480,14 +20488,15 @@ var ProxyWasmRunner = class {
20480
20488
  const local = this.hostFunctions.getLocalResponse();
20481
20489
  const responseHeaders2 = results.onRequestBody.output.response.headers;
20482
20490
  this.hostFunctions.resetLocalResponse();
20483
- const contentType2 = HeaderManager.firstValue(responseHeaders2["content-type"]) || "text/plain";
20491
+ const mergedHeaders = local.headers.length > 0 ? HeaderManager.appendMerge(responseHeaders2, HeaderManager.tuplesToRecord(local.headers)) : responseHeaders2;
20492
+ const contentType2 = HeaderManager.firstValue(mergedHeaders["content-type"]) || "text/plain";
20484
20493
  const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
20485
20494
  return {
20486
20495
  hookResults: results,
20487
20496
  finalResponse: {
20488
20497
  status: local.statusCode,
20489
20498
  statusText: local.statusText,
20490
- headers: responseHeaders2,
20499
+ headers: mergedHeaders,
20491
20500
  body,
20492
20501
  contentType: contentType2,
20493
20502
  isBase64: isBase642
@@ -20657,16 +20666,17 @@ var ProxyWasmRunner = class {
20657
20666
  }
20658
20667
  if (results.onResponseHeaders.returnCode === 1 && this.hostFunctions.hasLocalResponse()) {
20659
20668
  const local = this.hostFunctions.getLocalResponse();
20660
- const headers = results.onResponseHeaders.output.response.headers;
20669
+ const responseHeaders2 = results.onResponseHeaders.output.response.headers;
20661
20670
  this.hostFunctions.resetLocalResponse();
20662
- const contentType2 = HeaderManager.firstValue(headers["content-type"]) || "text/plain";
20671
+ const mergedHeaders = local.headers.length > 0 ? HeaderManager.appendMerge(responseHeaders2, HeaderManager.tuplesToRecord(local.headers)) : responseHeaders2;
20672
+ const contentType2 = HeaderManager.firstValue(mergedHeaders["content-type"]) || "text/plain";
20663
20673
  const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
20664
20674
  return {
20665
20675
  hookResults: results,
20666
20676
  finalResponse: {
20667
20677
  status: local.statusCode,
20668
20678
  statusText: local.statusText,
20669
- headers,
20679
+ headers: mergedHeaders,
20670
20680
  body,
20671
20681
  contentType: contentType2,
20672
20682
  isBase64: isBase642
@@ -20700,16 +20710,17 @@ var ProxyWasmRunner = class {
20700
20710
  }
20701
20711
  if (results.onResponseBody.returnCode === 1 && this.hostFunctions.hasLocalResponse()) {
20702
20712
  const local = this.hostFunctions.getLocalResponse();
20703
- const headers = results.onResponseBody.output.response.headers;
20713
+ const responseHeaders2 = results.onResponseBody.output.response.headers;
20704
20714
  this.hostFunctions.resetLocalResponse();
20705
- const contentType2 = HeaderManager.firstValue(headers["content-type"]) || "text/plain";
20715
+ const mergedHeaders = local.headers.length > 0 ? HeaderManager.appendMerge(responseHeaders2, HeaderManager.tuplesToRecord(local.headers)) : responseHeaders2;
20716
+ const contentType2 = HeaderManager.firstValue(mergedHeaders["content-type"]) || "text/plain";
20706
20717
  const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
20707
20718
  return {
20708
20719
  hookResults: results,
20709
20720
  finalResponse: {
20710
20721
  status: local.statusCode,
20711
20722
  statusText: local.statusText,
20712
- headers,
20723
+ headers: mergedHeaders,
20713
20724
  body,
20714
20725
  contentType: contentType2,
20715
20726
  isBase64: isBase642
@@ -21084,7 +21095,9 @@ var ProxyWasmRunner = class {
21084
21095
  }
21085
21096
  }
21086
21097
  createImports() {
21087
- const wasi = new WASI({ version: "preview1", env: this.dictionary.getAll() });
21098
+ const dictEnv = this.dictionary.getAll();
21099
+ const wasiEnv = Object.keys(dictEnv).length === 0 ? { __FASTEDGE_RUNNER__: "1" } : dictEnv;
21100
+ const wasi = new WASI({ version: "preview1", env: wasiEnv });
21088
21101
  const wasiImport = wasi.wasiImport;
21089
21102
  return {
21090
21103
  env: this.hostFunctions.createImports(),