@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.
@@ -18446,13 +18446,11 @@ var import_node_wasi = require("node:wasi");
18446
18446
  var textEncoder = new TextEncoder();
18447
18447
  var textDecoder = new TextDecoder();
18448
18448
  var MemoryManager = class {
18449
- constructor() {
18450
- this.memory = null;
18451
- this.instance = null;
18452
- this.hostAllocOffset = 0;
18453
- this.logCallback = null;
18454
- this.isInitializing = false;
18455
- }
18449
+ memory = null;
18450
+ instance = null;
18451
+ hostAllocOffset = 0;
18452
+ logCallback = null;
18453
+ isInitializing = false;
18456
18454
  setMemory(memory) {
18457
18455
  this.memory = memory;
18458
18456
  }
@@ -18615,7 +18613,7 @@ var MemoryManager = class {
18615
18613
 
18616
18614
  // server/runner/HeaderManager.ts
18617
18615
  var textEncoder2 = new TextEncoder();
18618
- var HeaderManager = class {
18616
+ var HeaderManager = class _HeaderManager {
18619
18617
  // Read a header value as a single string. For multi-valued headers (string[]) returns the first.
18620
18618
  // Use when callers know the header is conventionally single-valued (content-type, host, location, etc.)
18621
18619
  // and need to satisfy APIs that take a string.
@@ -18638,7 +18636,7 @@ var HeaderManager = class {
18638
18636
  return flat;
18639
18637
  }
18640
18638
  static normalize(headers) {
18641
- const normalized = {};
18639
+ const normalized = /* @__PURE__ */ Object.create(null);
18642
18640
  for (const [key, value] of Object.entries(headers)) {
18643
18641
  const k = key.toLowerCase();
18644
18642
  if (Array.isArray(value)) {
@@ -18649,6 +18647,30 @@ var HeaderManager = class {
18649
18647
  }
18650
18648
  return normalized;
18651
18649
  }
18650
+ // Append-merge two header records: for keys present in both, values are
18651
+ // concatenated into a string[] rather than the right-hand side overwriting
18652
+ // the left. Keys are lowercased on the way in (consistent with `normalize`).
18653
+ //
18654
+ // Used by the runner to combine request-phase response-header state with
18655
+ // the origin's response headers, mirroring how Envoy serves
18656
+ // `add_http_response_header` calls issued during onRequestHeaders /
18657
+ // onRequestBody against the actual upstream response — both values survive
18658
+ // as a multi-value list (preserving the proxy-wasm cross-phase pattern).
18659
+ static appendMerge(left, right) {
18660
+ const result = _HeaderManager.normalize(left);
18661
+ for (const [key, value] of Object.entries(right)) {
18662
+ const k = key.toLowerCase();
18663
+ const incoming = Array.isArray(value) ? value.map(String) : [String(value)];
18664
+ if (Object.hasOwn(result, k)) {
18665
+ const existing = result[k];
18666
+ const existingArr = Array.isArray(existing) ? existing : [existing];
18667
+ result[k] = [...existingArr, ...incoming];
18668
+ } else {
18669
+ result[k] = incoming.length === 1 ? incoming[0] : incoming;
18670
+ }
18671
+ }
18672
+ return result;
18673
+ }
18652
18674
  static serialize(headers) {
18653
18675
  const pairs = Object.entries(headers);
18654
18676
  const numPairs = pairs.length;
@@ -18827,20 +18849,18 @@ var HeaderManager = class {
18827
18849
 
18828
18850
  // server/runner/PropertyResolver.ts
18829
18851
  var PropertyResolver = class {
18830
- constructor() {
18831
- this.properties = {};
18832
- this.requestHeaders = {};
18833
- this.requestMethod = "GET";
18834
- this.requestPath = "/";
18835
- this.requestScheme = "https";
18836
- this.requestUrl = "";
18837
- this.requestHost = "";
18838
- this.requestQuery = "";
18839
- this.requestExtension = "";
18840
- this.responseHeaders = {};
18841
- this.responseStatus = 200;
18842
- this.responseStatusText = "OK";
18843
- }
18852
+ properties = {};
18853
+ requestHeaders = {};
18854
+ requestMethod = "GET";
18855
+ requestPath = "/";
18856
+ requestScheme = "https";
18857
+ requestUrl = "";
18858
+ requestHost = "";
18859
+ requestQuery = "";
18860
+ requestExtension = "";
18861
+ responseHeaders = {};
18862
+ responseStatus = 200;
18863
+ responseStatusText = "OK";
18844
18864
  setProperties(properties) {
18845
18865
  this.properties = properties;
18846
18866
  }
@@ -19032,6 +19052,7 @@ var PropertyResolver = class {
19032
19052
 
19033
19053
  // server/fastedge-host/SecretStore.ts
19034
19054
  var SecretStore = class {
19055
+ secrets;
19035
19056
  constructor(initialSecrets) {
19036
19057
  this.secrets = /* @__PURE__ */ new Map();
19037
19058
  if (initialSecrets) {
@@ -19114,6 +19135,7 @@ var SecretStore = class {
19114
19135
 
19115
19136
  // server/fastedge-host/Dictionary.ts
19116
19137
  var Dictionary = class {
19138
+ data;
19117
19139
  constructor(initialData) {
19118
19140
  this.data = /* @__PURE__ */ new Map();
19119
19141
  if (initialData) {
@@ -19281,26 +19303,33 @@ function createFastEdgeHostFunctions(memory, secretStore, dictionary, logDebug)
19281
19303
  // server/runner/HostFunctions.ts
19282
19304
  var textEncoder3 = new TextEncoder();
19283
19305
  var HostFunctions = class {
19306
+ memory;
19307
+ propertyResolver;
19308
+ propertyAccessControl;
19309
+ getCurrentHook;
19310
+ logs = [];
19311
+ requestHeaders = [];
19312
+ responseHeaders = [];
19313
+ requestBody = "";
19314
+ responseBody = "";
19315
+ vmConfig = "";
19316
+ pluginConfig = "";
19317
+ currentContextId = 1;
19318
+ lastHostCall = null;
19319
+ debug = false;
19320
+ currentLogLevel = 0 /* Trace */;
19321
+ // Default to show all logs
19322
+ // http_call state
19323
+ nextTokenId = 0;
19324
+ pendingHttpCall = null;
19325
+ httpCallResponse = null;
19326
+ streamClosed = false;
19327
+ // Local response state (from proxy_send_local_response / send_http_response)
19328
+ localResponse = null;
19329
+ // FastEdge extensions
19330
+ secretStore;
19331
+ dictionary;
19284
19332
  constructor(memory, propertyResolver, propertyAccessControl, getCurrentHook, debug = false, secretStore, dictionary) {
19285
- this.logs = [];
19286
- this.requestHeaders = [];
19287
- this.responseHeaders = [];
19288
- this.requestBody = "";
19289
- this.responseBody = "";
19290
- this.vmConfig = "";
19291
- this.pluginConfig = "";
19292
- this.currentContextId = 1;
19293
- this.lastHostCall = null;
19294
- this.debug = false;
19295
- this.currentLogLevel = 0 /* Trace */;
19296
- // Default to show all logs
19297
- // http_call state
19298
- this.nextTokenId = 0;
19299
- this.pendingHttpCall = null;
19300
- this.httpCallResponse = null;
19301
- this.streamClosed = false;
19302
- // Local response state (from proxy_send_local_response / send_http_response)
19303
- this.localResponse = null;
19304
19333
  this.memory = memory;
19305
19334
  this.propertyResolver = propertyResolver;
19306
19335
  this.propertyAccessControl = propertyAccessControl;
@@ -20031,6 +20060,8 @@ var BUILT_IN_PROPERTIES = [
20031
20060
  }
20032
20061
  ];
20033
20062
  var PropertyAccessControl = class {
20063
+ builtInProperties;
20064
+ customProperties;
20034
20065
  constructor() {
20035
20066
  this.builtInProperties = /* @__PURE__ */ new Map();
20036
20067
  this.customProperties = /* @__PURE__ */ new Map();
@@ -20248,21 +20279,28 @@ var textEncoder4 = new TextEncoder();
20248
20279
  var BUILTIN_URL = "http://fastedge-builtin.debug";
20249
20280
  var BUILTIN_SHORTHAND = "built-in";
20250
20281
  var ProxyWasmRunner = class {
20282
+ module = null;
20283
+ // Compiled module (reused)
20284
+ instance = null;
20285
+ // Current instance (transient per hook)
20286
+ memory;
20287
+ propertyResolver;
20288
+ propertyAccessControl;
20289
+ currentHook = null;
20290
+ hostFunctions;
20291
+ logs = [];
20292
+ rootContextId = 1;
20293
+ nextContextId = 2;
20294
+ currentContextId = 1;
20295
+ isInitializing = false;
20296
+ debug = process.env.PROXY_RUNNER_DEBUG === "1";
20297
+ stateManager = null;
20298
+ secretStore;
20299
+ dictionary;
20300
+ dotenvEnabled = true;
20301
+ // Default to enabled
20302
+ dotenvPath = ".";
20251
20303
  constructor(fastEdgeConfig, dotenvEnabled = true) {
20252
- this.module = null;
20253
- // Compiled module (reused)
20254
- this.instance = null;
20255
- this.currentHook = null;
20256
- this.logs = [];
20257
- this.rootContextId = 1;
20258
- this.nextContextId = 2;
20259
- this.currentContextId = 1;
20260
- this.isInitializing = false;
20261
- this.debug = process.env.PROXY_RUNNER_DEBUG === "1";
20262
- this.stateManager = null;
20263
- this.dotenvEnabled = true;
20264
- // Default to enabled
20265
- this.dotenvPath = ".";
20266
20304
  this.memory = new MemoryManager();
20267
20305
  this.propertyResolver = new PropertyResolver();
20268
20306
  this.propertyAccessControl = new PropertyAccessControl();
@@ -20615,6 +20653,14 @@ var ProxyWasmRunner = class {
20615
20653
  `Fetch completed: ${responseStatus} ${responseStatusText}`
20616
20654
  );
20617
20655
  }
20656
+ const requestPhaseResponseHeaders = {
20657
+ ...results.onRequestHeaders.output.response.headers ?? {},
20658
+ ...results.onRequestBody.output.response.headers ?? {}
20659
+ };
20660
+ const mergedResponseHeaders = HeaderManager.appendMerge(
20661
+ requestPhaseResponseHeaders,
20662
+ responseHeaders
20663
+ );
20618
20664
  const responseCall = {
20619
20665
  ...call,
20620
20666
  request: {
@@ -20623,7 +20669,7 @@ var ProxyWasmRunner = class {
20623
20669
  body: modifiedRequestBody
20624
20670
  },
20625
20671
  response: {
20626
- headers: responseHeaders,
20672
+ headers: mergedResponseHeaders,
20627
20673
  body: responseBody,
20628
20674
  status: responseStatus,
20629
20675
  statusText: responseStatusText
@@ -20645,6 +20691,25 @@ var ProxyWasmRunner = class {
20645
20691
  "system"
20646
20692
  );
20647
20693
  }
20694
+ if (results.onResponseHeaders.returnCode === 1 && this.hostFunctions.hasLocalResponse()) {
20695
+ const local = this.hostFunctions.getLocalResponse();
20696
+ const headers = results.onResponseHeaders.output.response.headers;
20697
+ this.hostFunctions.resetLocalResponse();
20698
+ const contentType2 = HeaderManager.firstValue(headers["content-type"]) || "text/plain";
20699
+ const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
20700
+ return {
20701
+ hookResults: results,
20702
+ finalResponse: {
20703
+ status: local.statusCode,
20704
+ statusText: local.statusText,
20705
+ headers,
20706
+ body,
20707
+ contentType: contentType2,
20708
+ isBase64: isBase642
20709
+ },
20710
+ calculatedProperties: this.propertyResolver.getCalculatedProperties()
20711
+ };
20712
+ }
20648
20713
  const headersAfterResponseHeaders = results.onResponseHeaders.output.response.headers;
20649
20714
  const propertiesAfterResponseHeaders = results.onResponseHeaders.properties;
20650
20715
  this.logDebug(
@@ -20669,6 +20734,25 @@ var ProxyWasmRunner = class {
20669
20734
  "system"
20670
20735
  );
20671
20736
  }
20737
+ if (results.onResponseBody.returnCode === 1 && this.hostFunctions.hasLocalResponse()) {
20738
+ const local = this.hostFunctions.getLocalResponse();
20739
+ const headers = results.onResponseBody.output.response.headers;
20740
+ this.hostFunctions.resetLocalResponse();
20741
+ const contentType2 = HeaderManager.firstValue(headers["content-type"]) || "text/plain";
20742
+ const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
20743
+ return {
20744
+ hookResults: results,
20745
+ finalResponse: {
20746
+ status: local.statusCode,
20747
+ statusText: local.statusText,
20748
+ headers,
20749
+ body,
20750
+ contentType: contentType2,
20751
+ isBase64: isBase642
20752
+ },
20753
+ calculatedProperties: this.propertyResolver.getCalculatedProperties()
20754
+ };
20755
+ }
20672
20756
  const finalHeaders = results.onResponseBody.output.response.headers;
20673
20757
  const finalBody = results.onResponseBody.output.response.body;
20674
20758
  this.logDebug(`Final response body length: ${finalBody.length}`);
@@ -21145,7 +21229,7 @@ var ProxyWasmRunner = class {
21145
21229
  /**
21146
21230
  * Not supported for Proxy-WASM (HTTP WASM only)
21147
21231
  */
21148
- async execute(request) {
21232
+ async execute(_request) {
21149
21233
  throw new Error(
21150
21234
  "execute() is not supported for Proxy-WASM. Use callHook() or callFullFlow() instead."
21151
21235
  );
@@ -21309,21 +21393,22 @@ async function isLegacySyncWasm(bufferOrPath) {
21309
21393
 
21310
21394
  // server/runner/HttpWasmRunner.ts
21311
21395
  var HttpWasmRunner = class {
21396
+ process = null;
21397
+ port = null;
21398
+ cliPath = null;
21399
+ tempWasmPath = null;
21400
+ currentWasmPath = null;
21401
+ // resolved path used when spawning
21402
+ logs = [];
21403
+ stateManager = null;
21404
+ portManager;
21405
+ dotenvEnabled = true;
21406
+ dotenvPath = null;
21407
+ /** Pinned ports bypass PortManager allocation and must not be released back to it. */
21408
+ isPinnedPort = false;
21409
+ /** @deprecated Legacy sync support — remove when #[fastedge::http] is retired */
21410
+ isLegacySync = false;
21312
21411
  constructor(portManager, dotenvEnabled = true) {
21313
- this.process = null;
21314
- this.port = null;
21315
- this.cliPath = null;
21316
- this.tempWasmPath = null;
21317
- this.currentWasmPath = null;
21318
- // resolved path used when spawning
21319
- this.logs = [];
21320
- this.stateManager = null;
21321
- this.dotenvEnabled = true;
21322
- this.dotenvPath = null;
21323
- /** Pinned ports bypass PortManager allocation and must not be released back to it. */
21324
- this.isPinnedPort = false;
21325
- /** @deprecated Legacy sync support — remove when #[fastedge::http] is retired */
21326
- this.isLegacySync = false;
21327
21412
  this.portManager = portManager;
21328
21413
  this.dotenvEnabled = dotenvEnabled;
21329
21414
  }
@@ -21723,12 +21808,10 @@ function parseFetchHeaders(headers) {
21723
21808
  // server/runner/PortManager.ts
21724
21809
  var import_net = require("net");
21725
21810
  var PortManager = class {
21726
- constructor() {
21727
- this.minPort = 8100;
21728
- this.maxPort = 8199;
21729
- this.allocatedPorts = /* @__PURE__ */ new Set();
21730
- this.lastAllocatedPort = this.minPort - 1;
21731
- }
21811
+ minPort = 8100;
21812
+ maxPort = 8199;
21813
+ allocatedPorts = /* @__PURE__ */ new Set();
21814
+ lastAllocatedPort = this.minPort - 1;
21732
21815
  /**
21733
21816
  * Check whether a port is actually free at the OS level.
21734
21817
  * This is necessary when multiple server processes run simultaneously —