@gcoredev/fastedge-test 0.2.1 → 0.2.3
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/bin/fastedge-debug.js +38 -3
- package/dist/fastedge-cli/METADATA.json +1 -1
- package/dist/fastedge-cli/fastedge-run-darwin-arm64 +0 -0
- package/dist/fastedge-cli/fastedge-run-linux-x64 +0 -0
- package/dist/fastedge-cli/fastedge-run.exe +0 -0
- package/dist/lib/index.cjs +59 -28
- package/dist/lib/index.js +62 -29
- package/dist/lib/runner/HostFunctions.d.ts +1 -0
- package/dist/lib/test-framework/index.cjs +59 -28
- package/dist/lib/test-framework/index.js +61 -29
- package/dist/lib/utils/fastedge-cli.d.ts +36 -1
- package/dist/server.js +29 -29
- package/docs/DEBUGGER.md +24 -4
- package/docs/TEST_CONFIG.md +19 -19
- package/docs/TEST_FRAMEWORK.md +7 -7
- package/package.json +2 -2
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createRequire as __cr } from 'node:module'; const require = __cr(import.meta.url);
|
|
1
2
|
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -19288,7 +19289,13 @@ var HostFunctions = class {
|
|
|
19288
19289
|
pendingHttpCall = null;
|
|
19289
19290
|
httpCallResponse = null;
|
|
19290
19291
|
streamClosed = false;
|
|
19291
|
-
// Local response state (from proxy_send_local_response / send_http_response)
|
|
19292
|
+
// Local response state (from proxy_send_local_response / send_http_response).
|
|
19293
|
+
// `headers` carries the additional headers passed as the 4th argument of
|
|
19294
|
+
// `send_http_response`; ProxyWasmRunner merges these into finalResponse at
|
|
19295
|
+
// the short-circuit points so they reach the caller alongside any headers
|
|
19296
|
+
// accumulated via stream_context.headers.response.add() in the same hook.
|
|
19297
|
+
// Stored as tuples to preserve order and duplicate-name semantics (e.g. for
|
|
19298
|
+
// multi-value Set-Cookie additions).
|
|
19292
19299
|
localResponse = null;
|
|
19293
19300
|
// FastEdge extensions
|
|
19294
19301
|
secretStore;
|
|
@@ -19638,12 +19645,13 @@ var HostFunctions = class {
|
|
|
19638
19645
|
);
|
|
19639
19646
|
const statusText = this.memory.readString(statusCodePtr, statusCodeLen);
|
|
19640
19647
|
const body = this.memory.readBytes(bodyPtr, bodyLen);
|
|
19648
|
+
let headers = [];
|
|
19641
19649
|
if (headerPairsLen > 0) {
|
|
19642
19650
|
const headerBytes = this.memory.readBytes(headerPairsPtr, headerPairsLen);
|
|
19643
|
-
|
|
19644
|
-
this.logDebug(`send_local_response headers
|
|
19651
|
+
headers = HeaderManager.deserializeBinaryToTuples(headerBytes);
|
|
19652
|
+
this.logDebug(`send_local_response headers: ${JSON.stringify(headers)}`);
|
|
19645
19653
|
}
|
|
19646
|
-
this.localResponse = { statusCode, statusText, body };
|
|
19654
|
+
this.localResponse = { statusCode, statusText, body, headers };
|
|
19647
19655
|
this.logs.push({
|
|
19648
19656
|
level: 1,
|
|
19649
19657
|
message: `local_response status=${statusCode} ${statusText} bodyLen=${body.byteLength} grpc=${grpcStatus}`
|
|
@@ -20437,14 +20445,15 @@ var ProxyWasmRunner = class {
|
|
|
20437
20445
|
const local = this.hostFunctions.getLocalResponse();
|
|
20438
20446
|
const responseHeaders2 = results.onRequestHeaders.output.response.headers;
|
|
20439
20447
|
this.hostFunctions.resetLocalResponse();
|
|
20440
|
-
const
|
|
20448
|
+
const mergedHeaders = local.headers.length > 0 ? HeaderManager.appendMerge(responseHeaders2, HeaderManager.tuplesToRecord(local.headers)) : responseHeaders2;
|
|
20449
|
+
const contentType2 = HeaderManager.firstValue(mergedHeaders["content-type"]) || "text/plain";
|
|
20441
20450
|
const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
|
|
20442
20451
|
return {
|
|
20443
20452
|
hookResults: results,
|
|
20444
20453
|
finalResponse: {
|
|
20445
20454
|
status: local.statusCode,
|
|
20446
20455
|
statusText: local.statusText,
|
|
20447
|
-
headers:
|
|
20456
|
+
headers: mergedHeaders,
|
|
20448
20457
|
body,
|
|
20449
20458
|
contentType: contentType2,
|
|
20450
20459
|
isBase64: isBase642
|
|
@@ -20480,14 +20489,15 @@ var ProxyWasmRunner = class {
|
|
|
20480
20489
|
const local = this.hostFunctions.getLocalResponse();
|
|
20481
20490
|
const responseHeaders2 = results.onRequestBody.output.response.headers;
|
|
20482
20491
|
this.hostFunctions.resetLocalResponse();
|
|
20483
|
-
const
|
|
20492
|
+
const mergedHeaders = local.headers.length > 0 ? HeaderManager.appendMerge(responseHeaders2, HeaderManager.tuplesToRecord(local.headers)) : responseHeaders2;
|
|
20493
|
+
const contentType2 = HeaderManager.firstValue(mergedHeaders["content-type"]) || "text/plain";
|
|
20484
20494
|
const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
|
|
20485
20495
|
return {
|
|
20486
20496
|
hookResults: results,
|
|
20487
20497
|
finalResponse: {
|
|
20488
20498
|
status: local.statusCode,
|
|
20489
20499
|
statusText: local.statusText,
|
|
20490
|
-
headers:
|
|
20500
|
+
headers: mergedHeaders,
|
|
20491
20501
|
body,
|
|
20492
20502
|
contentType: contentType2,
|
|
20493
20503
|
isBase64: isBase642
|
|
@@ -20657,16 +20667,17 @@ var ProxyWasmRunner = class {
|
|
|
20657
20667
|
}
|
|
20658
20668
|
if (results.onResponseHeaders.returnCode === 1 && this.hostFunctions.hasLocalResponse()) {
|
|
20659
20669
|
const local = this.hostFunctions.getLocalResponse();
|
|
20660
|
-
const
|
|
20670
|
+
const responseHeaders2 = results.onResponseHeaders.output.response.headers;
|
|
20661
20671
|
this.hostFunctions.resetLocalResponse();
|
|
20662
|
-
const
|
|
20672
|
+
const mergedHeaders = local.headers.length > 0 ? HeaderManager.appendMerge(responseHeaders2, HeaderManager.tuplesToRecord(local.headers)) : responseHeaders2;
|
|
20673
|
+
const contentType2 = HeaderManager.firstValue(mergedHeaders["content-type"]) || "text/plain";
|
|
20663
20674
|
const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
|
|
20664
20675
|
return {
|
|
20665
20676
|
hookResults: results,
|
|
20666
20677
|
finalResponse: {
|
|
20667
20678
|
status: local.statusCode,
|
|
20668
20679
|
statusText: local.statusText,
|
|
20669
|
-
headers,
|
|
20680
|
+
headers: mergedHeaders,
|
|
20670
20681
|
body,
|
|
20671
20682
|
contentType: contentType2,
|
|
20672
20683
|
isBase64: isBase642
|
|
@@ -20700,16 +20711,17 @@ var ProxyWasmRunner = class {
|
|
|
20700
20711
|
}
|
|
20701
20712
|
if (results.onResponseBody.returnCode === 1 && this.hostFunctions.hasLocalResponse()) {
|
|
20702
20713
|
const local = this.hostFunctions.getLocalResponse();
|
|
20703
|
-
const
|
|
20714
|
+
const responseHeaders2 = results.onResponseBody.output.response.headers;
|
|
20704
20715
|
this.hostFunctions.resetLocalResponse();
|
|
20705
|
-
const
|
|
20716
|
+
const mergedHeaders = local.headers.length > 0 ? HeaderManager.appendMerge(responseHeaders2, HeaderManager.tuplesToRecord(local.headers)) : responseHeaders2;
|
|
20717
|
+
const contentType2 = HeaderManager.firstValue(mergedHeaders["content-type"]) || "text/plain";
|
|
20706
20718
|
const { body, isBase64: isBase642 } = encodeLocalResponseBody(local.body, contentType2);
|
|
20707
20719
|
return {
|
|
20708
20720
|
hookResults: results,
|
|
20709
20721
|
finalResponse: {
|
|
20710
20722
|
status: local.statusCode,
|
|
20711
20723
|
statusText: local.statusText,
|
|
20712
|
-
headers,
|
|
20724
|
+
headers: mergedHeaders,
|
|
20713
20725
|
body,
|
|
20714
20726
|
contentType: contentType2,
|
|
20715
20727
|
isBase64: isBase642
|
|
@@ -21084,7 +21096,9 @@ var ProxyWasmRunner = class {
|
|
|
21084
21096
|
}
|
|
21085
21097
|
}
|
|
21086
21098
|
createImports() {
|
|
21087
|
-
const
|
|
21099
|
+
const dictEnv = this.dictionary.getAll();
|
|
21100
|
+
const wasiEnv = Object.keys(dictEnv).length === 0 ? { __FASTEDGE_RUNNER__: "1" } : dictEnv;
|
|
21101
|
+
const wasi = new WASI({ version: "preview1", env: wasiEnv });
|
|
21088
21102
|
const wasiImport = wasi.wasiImport;
|
|
21089
21103
|
return {
|
|
21090
21104
|
env: this.hostFunctions.createImports(),
|
|
@@ -21241,7 +21255,7 @@ import { spawn, execSync as execSync2 } from "child_process";
|
|
|
21241
21255
|
|
|
21242
21256
|
// server/utils/fastedge-cli.ts
|
|
21243
21257
|
import { execSync } from "child_process";
|
|
21244
|
-
import { existsSync, chmodSync } from "fs";
|
|
21258
|
+
import { existsSync, chmodSync, readFileSync } from "fs";
|
|
21245
21259
|
import { join, dirname } from "path";
|
|
21246
21260
|
import { fileURLToPath } from "url";
|
|
21247
21261
|
import os from "os";
|
|
@@ -21258,19 +21272,37 @@ function getCliBinaryName() {
|
|
|
21258
21272
|
throw new Error(`Unsupported platform: ${os.platform()}`);
|
|
21259
21273
|
}
|
|
21260
21274
|
}
|
|
21261
|
-
function
|
|
21275
|
+
function getPackageRoot(startDir = _currentDir) {
|
|
21276
|
+
let dir = startDir;
|
|
21277
|
+
while (true) {
|
|
21278
|
+
const pkgPath = join(dir, "package.json");
|
|
21279
|
+
if (existsSync(pkgPath)) {
|
|
21280
|
+
try {
|
|
21281
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
21282
|
+
if (pkg.name === "@gcoredev/fastedge-test") return dir;
|
|
21283
|
+
} catch {
|
|
21284
|
+
}
|
|
21285
|
+
}
|
|
21286
|
+
const parent = dirname(dir);
|
|
21287
|
+
if (parent === dir) return null;
|
|
21288
|
+
dir = parent;
|
|
21289
|
+
}
|
|
21290
|
+
}
|
|
21291
|
+
function getBundledCliPaths(startDir = _currentDir) {
|
|
21262
21292
|
const binaryName = getCliBinaryName();
|
|
21263
|
-
|
|
21264
|
-
|
|
21265
|
-
|
|
21266
|
-
|
|
21267
|
-
|
|
21268
|
-
|
|
21269
|
-
|
|
21270
|
-
|
|
21271
|
-
|
|
21272
|
-
join(
|
|
21273
|
-
|
|
21293
|
+
const candidates = [];
|
|
21294
|
+
const root = getPackageRoot(startDir);
|
|
21295
|
+
if (root) {
|
|
21296
|
+
candidates.push(
|
|
21297
|
+
join(root, "dist", "fastedge-cli", binaryName),
|
|
21298
|
+
join(root, "fastedge-run", binaryName)
|
|
21299
|
+
);
|
|
21300
|
+
}
|
|
21301
|
+
candidates.push(
|
|
21302
|
+
join(startDir, "fastedge-cli", binaryName),
|
|
21303
|
+
join(startDir, "..", "fastedge-cli", binaryName)
|
|
21304
|
+
);
|
|
21305
|
+
return candidates;
|
|
21274
21306
|
}
|
|
21275
21307
|
function ensureExecutable(binaryPath) {
|
|
21276
21308
|
if (process.platform !== "win32") {
|
|
@@ -21308,7 +21340,7 @@ async function findFastEdgeRunCli() {
|
|
|
21308
21340
|
} catch (error) {
|
|
21309
21341
|
}
|
|
21310
21342
|
throw new Error(
|
|
21311
|
-
"fastedge-run CLI not found in any of these locations:\n 1. FASTEDGE_RUN_PATH environment variable\n 2. Bundled
|
|
21343
|
+
"fastedge-run CLI not found in any of these locations:\n 1. FASTEDGE_RUN_PATH environment variable\n 2. Bundled inside the @gcoredev/fastedge-test package (dist/fastedge-cli/<binary> when installed, fastedge-run/<binary> in the source tree)\n 3. System PATH (which/where fastedge-run)\n\nTo fix this:\n - Set FASTEDGE_RUN_PATH to a fastedge-run binary you have locally, or\n - Install fastedge-run in PATH: cargo install fastedge-run, or\n - Reinstall @gcoredev/fastedge-test to restore the bundled binary (or, when developing this repo, place the platform binary in fastedge-run/)"
|
|
21312
21344
|
);
|
|
21313
21345
|
}
|
|
21314
21346
|
|
|
@@ -3,9 +3,44 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Discovers the FastEdge-run CLI binary in the following order:
|
|
5
5
|
* 1. FASTEDGE_RUN_PATH environment variable
|
|
6
|
-
* 2. Bundled binary
|
|
6
|
+
* 2. Bundled binary inside the @gcoredev/fastedge-test package, anchored on
|
|
7
|
+
* the package root (see getPackageRoot):
|
|
8
|
+
* • dist/fastedge-cli/<binary> — published npm layout
|
|
9
|
+
* • fastedge-run/<binary> — in-repo source/dev layout
|
|
7
10
|
* 3. PATH (using 'which' or 'where' command)
|
|
8
11
|
*/
|
|
12
|
+
/**
|
|
13
|
+
* Walk up from `startDir` until a package.json with name "@gcoredev/fastedge-test"
|
|
14
|
+
* is found. Anchoring on the package name (rather than hardcoded depths or an
|
|
15
|
+
* unbounded walk) keeps the search robust across bundle layouts and avoids
|
|
16
|
+
* climbing into a sibling package in workspace/monorepo installs.
|
|
17
|
+
*
|
|
18
|
+
* `startDir` defaults to the directory of this file (resolved at module load).
|
|
19
|
+
* It is overridable for tests so the resolver can be exercised against
|
|
20
|
+
* synthetic package layouts.
|
|
21
|
+
*/
|
|
22
|
+
export declare function getPackageRoot(startDir?: string): string | null;
|
|
23
|
+
/**
|
|
24
|
+
* Get possible bundled CLI paths.
|
|
25
|
+
*
|
|
26
|
+
* Two resolution modes, both contribute candidates:
|
|
27
|
+
*
|
|
28
|
+
* 1. **Package-root anchored** (primary) — when a `@gcoredev/fastedge-test`
|
|
29
|
+
* package.json can be located via `getPackageRoot`, candidates resolve
|
|
30
|
+
* against it: the published npm layout (`dist/fastedge-cli/`) and the
|
|
31
|
+
* in-repo source layout (`fastedge-run/`).
|
|
32
|
+
*
|
|
33
|
+
* 2. **startDir-relative fallback** — covers bundle layouts that ship
|
|
34
|
+
* without our package.json available nearby. Notably the VSCode extension
|
|
35
|
+
* copies `dist/server.js` and `dist/fastedge-cli/` into its own tree, so
|
|
36
|
+
* the walker can't anchor on our package root. The fallback lets the
|
|
37
|
+
* server bundle locate the sibling `fastedge-cli/` directory directly.
|
|
38
|
+
*
|
|
39
|
+
* `findFastEdgeRunCli` filters by existence, so listing extra candidates is
|
|
40
|
+
* safe — the first one that actually exists wins. `startDir` is overridable
|
|
41
|
+
* for tests.
|
|
42
|
+
*/
|
|
43
|
+
export declare function getBundledCliPaths(startDir?: string): string[];
|
|
9
44
|
/**
|
|
10
45
|
* Find the FastEdge-run CLI binary
|
|
11
46
|
* @returns The absolute path to the fastedge-run binary
|