@gcoredev/fastedge-test 0.2.0 → 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.
@@ -1 +1 @@
1
- {"fastedge_run_version": "v0.15.0"}
1
+ {"fastedge_run_version": "v0.16.5"}
Binary file
@@ -49,13 +49,11 @@ var import_node_wasi = require("node:wasi");
49
49
  var textEncoder = new TextEncoder();
50
50
  var textDecoder = new TextDecoder();
51
51
  var MemoryManager = class {
52
- constructor() {
53
- this.memory = null;
54
- this.instance = null;
55
- this.hostAllocOffset = 0;
56
- this.logCallback = null;
57
- this.isInitializing = false;
58
- }
52
+ memory = null;
53
+ instance = null;
54
+ hostAllocOffset = 0;
55
+ logCallback = null;
56
+ isInitializing = false;
59
57
  setMemory(memory) {
60
58
  this.memory = memory;
61
59
  }
@@ -218,7 +216,7 @@ var MemoryManager = class {
218
216
 
219
217
  // server/runner/HeaderManager.ts
220
218
  var textEncoder2 = new TextEncoder();
221
- var HeaderManager = class {
219
+ var HeaderManager = class _HeaderManager {
222
220
  // Read a header value as a single string. For multi-valued headers (string[]) returns the first.
223
221
  // Use when callers know the header is conventionally single-valued (content-type, host, location, etc.)
224
222
  // and need to satisfy APIs that take a string.
@@ -241,7 +239,7 @@ var HeaderManager = class {
241
239
  return flat;
242
240
  }
243
241
  static normalize(headers) {
244
- const normalized = {};
242
+ const normalized = /* @__PURE__ */ Object.create(null);
245
243
  for (const [key, value] of Object.entries(headers)) {
246
244
  const k = key.toLowerCase();
247
245
  if (Array.isArray(value)) {
@@ -252,6 +250,30 @@ var HeaderManager = class {
252
250
  }
253
251
  return normalized;
254
252
  }
253
+ // Append-merge two header records: for keys present in both, values are
254
+ // concatenated into a string[] rather than the right-hand side overwriting
255
+ // the left. Keys are lowercased on the way in (consistent with `normalize`).
256
+ //
257
+ // Used by the runner to combine request-phase response-header state with
258
+ // the origin's response headers, mirroring how Envoy serves
259
+ // `add_http_response_header` calls issued during onRequestHeaders /
260
+ // onRequestBody against the actual upstream response — both values survive
261
+ // as a multi-value list (preserving the proxy-wasm cross-phase pattern).
262
+ static appendMerge(left, right) {
263
+ const result = _HeaderManager.normalize(left);
264
+ for (const [key, value] of Object.entries(right)) {
265
+ const k = key.toLowerCase();
266
+ const incoming = Array.isArray(value) ? value.map(String) : [String(value)];
267
+ if (Object.hasOwn(result, k)) {
268
+ const existing = result[k];
269
+ const existingArr = Array.isArray(existing) ? existing : [existing];
270
+ result[k] = [...existingArr, ...incoming];
271
+ } else {
272
+ result[k] = incoming.length === 1 ? incoming[0] : incoming;
273
+ }
274
+ }
275
+ return result;
276
+ }
255
277
  static serialize(headers) {
256
278
  const pairs = Object.entries(headers);
257
279
  const numPairs = pairs.length;
@@ -430,20 +452,18 @@ var HeaderManager = class {
430
452
 
431
453
  // server/runner/PropertyResolver.ts
432
454
  var PropertyResolver = class {
433
- constructor() {
434
- this.properties = {};
435
- this.requestHeaders = {};
436
- this.requestMethod = "GET";
437
- this.requestPath = "/";
438
- this.requestScheme = "https";
439
- this.requestUrl = "";
440
- this.requestHost = "";
441
- this.requestQuery = "";
442
- this.requestExtension = "";
443
- this.responseHeaders = {};
444
- this.responseStatus = 200;
445
- this.responseStatusText = "OK";
446
- }
455
+ properties = {};
456
+ requestHeaders = {};
457
+ requestMethod = "GET";
458
+ requestPath = "/";
459
+ requestScheme = "https";
460
+ requestUrl = "";
461
+ requestHost = "";
462
+ requestQuery = "";
463
+ requestExtension = "";
464
+ responseHeaders = {};
465
+ responseStatus = 200;
466
+ responseStatusText = "OK";
447
467
  setProperties(properties) {
448
468
  this.properties = properties;
449
469
  }
@@ -635,6 +655,7 @@ var PropertyResolver = class {
635
655
 
636
656
  // server/fastedge-host/SecretStore.ts
637
657
  var SecretStore = class {
658
+ secrets;
638
659
  constructor(initialSecrets) {
639
660
  this.secrets = /* @__PURE__ */ new Map();
640
661
  if (initialSecrets) {
@@ -717,6 +738,7 @@ var SecretStore = class {
717
738
 
718
739
  // server/fastedge-host/Dictionary.ts
719
740
  var Dictionary = class {
741
+ data;
720
742
  constructor(initialData) {
721
743
  this.data = /* @__PURE__ */ new Map();
722
744
  if (initialData) {
@@ -884,26 +906,33 @@ function createFastEdgeHostFunctions(memory, secretStore, dictionary, logDebug)
884
906
  // server/runner/HostFunctions.ts
885
907
  var textEncoder3 = new TextEncoder();
886
908
  var HostFunctions = class {
909
+ memory;
910
+ propertyResolver;
911
+ propertyAccessControl;
912
+ getCurrentHook;
913
+ logs = [];
914
+ requestHeaders = [];
915
+ responseHeaders = [];
916
+ requestBody = "";
917
+ responseBody = "";
918
+ vmConfig = "";
919
+ pluginConfig = "";
920
+ currentContextId = 1;
921
+ lastHostCall = null;
922
+ debug = false;
923
+ currentLogLevel = 0 /* Trace */;
924
+ // Default to show all logs
925
+ // http_call state
926
+ nextTokenId = 0;
927
+ pendingHttpCall = null;
928
+ httpCallResponse = null;
929
+ streamClosed = false;
930
+ // Local response state (from proxy_send_local_response / send_http_response)
931
+ localResponse = null;
932
+ // FastEdge extensions
933
+ secretStore;
934
+ dictionary;
887
935
  constructor(memory, propertyResolver, propertyAccessControl, getCurrentHook, debug = false, secretStore, dictionary) {
888
- this.logs = [];
889
- this.requestHeaders = [];
890
- this.responseHeaders = [];
891
- this.requestBody = "";
892
- this.responseBody = "";
893
- this.vmConfig = "";
894
- this.pluginConfig = "";
895
- this.currentContextId = 1;
896
- this.lastHostCall = null;
897
- this.debug = false;
898
- this.currentLogLevel = 0 /* Trace */;
899
- // Default to show all logs
900
- // http_call state
901
- this.nextTokenId = 0;
902
- this.pendingHttpCall = null;
903
- this.httpCallResponse = null;
904
- this.streamClosed = false;
905
- // Local response state (from proxy_send_local_response / send_http_response)
906
- this.localResponse = null;
907
936
  this.memory = memory;
908
937
  this.propertyResolver = propertyResolver;
909
938
  this.propertyAccessControl = propertyAccessControl;
@@ -1634,6 +1663,8 @@ var BUILT_IN_PROPERTIES = [
1634
1663
  }
1635
1664
  ];
1636
1665
  var PropertyAccessControl = class {
1666
+ builtInProperties;
1667
+ customProperties;
1637
1668
  constructor() {
1638
1669
  this.builtInProperties = /* @__PURE__ */ new Map();
1639
1670
  this.customProperties = /* @__PURE__ */ new Map();
@@ -1851,21 +1882,28 @@ var textEncoder4 = new TextEncoder();
1851
1882
  var BUILTIN_URL = "http://fastedge-builtin.debug";
1852
1883
  var BUILTIN_SHORTHAND = "built-in";
1853
1884
  var ProxyWasmRunner = class {
1885
+ module = null;
1886
+ // Compiled module (reused)
1887
+ instance = null;
1888
+ // Current instance (transient per hook)
1889
+ memory;
1890
+ propertyResolver;
1891
+ propertyAccessControl;
1892
+ currentHook = null;
1893
+ hostFunctions;
1894
+ logs = [];
1895
+ rootContextId = 1;
1896
+ nextContextId = 2;
1897
+ currentContextId = 1;
1898
+ isInitializing = false;
1899
+ debug = process.env.PROXY_RUNNER_DEBUG === "1";
1900
+ stateManager = null;
1901
+ secretStore;
1902
+ dictionary;
1903
+ dotenvEnabled = true;
1904
+ // Default to enabled
1905
+ dotenvPath = ".";
1854
1906
  constructor(fastEdgeConfig, dotenvEnabled = true) {
1855
- this.module = null;
1856
- // Compiled module (reused)
1857
- this.instance = null;
1858
- this.currentHook = null;
1859
- this.logs = [];
1860
- this.rootContextId = 1;
1861
- this.nextContextId = 2;
1862
- this.currentContextId = 1;
1863
- this.isInitializing = false;
1864
- this.debug = process.env.PROXY_RUNNER_DEBUG === "1";
1865
- this.stateManager = null;
1866
- this.dotenvEnabled = true;
1867
- // Default to enabled
1868
- this.dotenvPath = ".";
1869
1907
  this.memory = new MemoryManager();
1870
1908
  this.propertyResolver = new PropertyResolver();
1871
1909
  this.propertyAccessControl = new PropertyAccessControl();
@@ -2218,6 +2256,14 @@ var ProxyWasmRunner = class {
2218
2256
  `Fetch completed: ${responseStatus} ${responseStatusText}`
2219
2257
  );
2220
2258
  }
2259
+ const requestPhaseResponseHeaders = {
2260
+ ...results.onRequestHeaders.output.response.headers ?? {},
2261
+ ...results.onRequestBody.output.response.headers ?? {}
2262
+ };
2263
+ const mergedResponseHeaders = HeaderManager.appendMerge(
2264
+ requestPhaseResponseHeaders,
2265
+ responseHeaders
2266
+ );
2221
2267
  const responseCall = {
2222
2268
  ...call,
2223
2269
  request: {
@@ -2226,7 +2272,7 @@ var ProxyWasmRunner = class {
2226
2272
  body: modifiedRequestBody
2227
2273
  },
2228
2274
  response: {
2229
- headers: responseHeaders,
2275
+ headers: mergedResponseHeaders,
2230
2276
  body: responseBody,
2231
2277
  status: responseStatus,
2232
2278
  statusText: responseStatusText
@@ -2248,6 +2294,25 @@ var ProxyWasmRunner = class {
2248
2294
  "system"
2249
2295
  );
2250
2296
  }
2297
+ if (results.onResponseHeaders.returnCode === 1 && this.hostFunctions.hasLocalResponse()) {
2298
+ const local = this.hostFunctions.getLocalResponse();
2299
+ const headers = results.onResponseHeaders.output.response.headers;
2300
+ this.hostFunctions.resetLocalResponse();
2301
+ const contentType2 = HeaderManager.firstValue(headers["content-type"]) || "text/plain";
2302
+ const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
2303
+ return {
2304
+ hookResults: results,
2305
+ finalResponse: {
2306
+ status: local.statusCode,
2307
+ statusText: local.statusText,
2308
+ headers,
2309
+ body,
2310
+ contentType: contentType2,
2311
+ isBase64: isBase642
2312
+ },
2313
+ calculatedProperties: this.propertyResolver.getCalculatedProperties()
2314
+ };
2315
+ }
2251
2316
  const headersAfterResponseHeaders = results.onResponseHeaders.output.response.headers;
2252
2317
  const propertiesAfterResponseHeaders = results.onResponseHeaders.properties;
2253
2318
  this.logDebug(
@@ -2272,6 +2337,25 @@ var ProxyWasmRunner = class {
2272
2337
  "system"
2273
2338
  );
2274
2339
  }
2340
+ if (results.onResponseBody.returnCode === 1 && this.hostFunctions.hasLocalResponse()) {
2341
+ const local = this.hostFunctions.getLocalResponse();
2342
+ const headers = results.onResponseBody.output.response.headers;
2343
+ this.hostFunctions.resetLocalResponse();
2344
+ const contentType2 = HeaderManager.firstValue(headers["content-type"]) || "text/plain";
2345
+ const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
2346
+ return {
2347
+ hookResults: results,
2348
+ finalResponse: {
2349
+ status: local.statusCode,
2350
+ statusText: local.statusText,
2351
+ headers,
2352
+ body,
2353
+ contentType: contentType2,
2354
+ isBase64: isBase642
2355
+ },
2356
+ calculatedProperties: this.propertyResolver.getCalculatedProperties()
2357
+ };
2358
+ }
2275
2359
  const finalHeaders = results.onResponseBody.output.response.headers;
2276
2360
  const finalBody = results.onResponseBody.output.response.body;
2277
2361
  this.logDebug(`Final response body length: ${finalBody.length}`);
@@ -2748,7 +2832,7 @@ var ProxyWasmRunner = class {
2748
2832
  /**
2749
2833
  * Not supported for Proxy-WASM (HTTP WASM only)
2750
2834
  */
2751
- async execute(request) {
2835
+ async execute(_request) {
2752
2836
  throw new Error(
2753
2837
  "execute() is not supported for Proxy-WASM. Use callHook() or callFullFlow() instead."
2754
2838
  );
@@ -2912,21 +2996,22 @@ async function isLegacySyncWasm(bufferOrPath) {
2912
2996
 
2913
2997
  // server/runner/HttpWasmRunner.ts
2914
2998
  var HttpWasmRunner = class {
2999
+ process = null;
3000
+ port = null;
3001
+ cliPath = null;
3002
+ tempWasmPath = null;
3003
+ currentWasmPath = null;
3004
+ // resolved path used when spawning
3005
+ logs = [];
3006
+ stateManager = null;
3007
+ portManager;
3008
+ dotenvEnabled = true;
3009
+ dotenvPath = null;
3010
+ /** Pinned ports bypass PortManager allocation and must not be released back to it. */
3011
+ isPinnedPort = false;
3012
+ /** @deprecated Legacy sync support — remove when #[fastedge::http] is retired */
3013
+ isLegacySync = false;
2915
3014
  constructor(portManager, dotenvEnabled = true) {
2916
- this.process = null;
2917
- this.port = null;
2918
- this.cliPath = null;
2919
- this.tempWasmPath = null;
2920
- this.currentWasmPath = null;
2921
- // resolved path used when spawning
2922
- this.logs = [];
2923
- this.stateManager = null;
2924
- this.dotenvEnabled = true;
2925
- this.dotenvPath = null;
2926
- /** Pinned ports bypass PortManager allocation and must not be released back to it. */
2927
- this.isPinnedPort = false;
2928
- /** @deprecated Legacy sync support — remove when #[fastedge::http] is retired */
2929
- this.isLegacySync = false;
2930
3015
  this.portManager = portManager;
2931
3016
  this.dotenvEnabled = dotenvEnabled;
2932
3017
  }
@@ -3326,12 +3411,10 @@ function parseFetchHeaders(headers) {
3326
3411
  // server/runner/PortManager.ts
3327
3412
  var import_net = require("net");
3328
3413
  var PortManager = class {
3329
- constructor() {
3330
- this.minPort = 8100;
3331
- this.maxPort = 8199;
3332
- this.allocatedPorts = /* @__PURE__ */ new Set();
3333
- this.lastAllocatedPort = this.minPort - 1;
3334
- }
3414
+ minPort = 8100;
3415
+ maxPort = 8199;
3416
+ allocatedPorts = /* @__PURE__ */ new Set();
3417
+ lastAllocatedPort = this.minPort - 1;
3335
3418
  /**
3336
3419
  * Check whether a port is actually free at the OS level.
3337
3420
  * This is necessary when multiple server processes run simultaneously —
@@ -3391,6 +3474,7 @@ var PortManager = class {
3391
3474
 
3392
3475
  // server/runner/WasmRunnerFactory.ts
3393
3476
  var WasmRunnerFactory = class {
3477
+ portManager;
3394
3478
  constructor() {
3395
3479
  this.portManager = new PortManager();
3396
3480
  }