@forge/tunnel 5.0.1-next.3 → 5.0.1-next.5
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/CHANGELOG.md +17 -0
- package/out/command/interactors/function-change-watcher.js +9 -6
- package/out/command/interactors/multi-compiler-watcher.js +13 -3
- package/out/command/interactors/tunnel-interactor.js +48 -47
- package/out/command/start-tunnel-command.js +55 -38
- package/out/graphql/tunnel-graphql-client.js +1 -0
- package/out/index.d.ts +1 -0
- package/out/index.d.ts.map +1 -1
- package/out/index.js +1 -0
- package/out/sandbox/index.d.ts +2 -0
- package/out/sandbox/index.d.ts.map +1 -0
- package/out/sandbox/index.js +4 -0
- package/out/sandbox/node-sandbox.d.ts +11 -0
- package/out/sandbox/node-sandbox.d.ts.map +1 -0
- package/out/sandbox/node-sandbox.js +62 -0
- package/out/sandbox/sandbox-runner.d.ts +3 -0
- package/out/sandbox/sandbox-runner.d.ts.map +1 -0
- package/out/sandbox/sandbox-runner.js +9 -0
- package/out/servers/csp-reporter-server.js +7 -3
- package/out/servers/custom-ui-tunnel-server.js +8 -5
- package/out/servers/dev-server.js +44 -33
- package/out/servers/native-ui-tunnel-server.js +10 -3
- package/out/servers/resource-tunnel-server.js +35 -30
- package/out/services/create-tunnel-service.js +5 -3
- package/out/services/local-invocation-service.js +11 -9
- package/out/services/register-tunnel-service.js +3 -0
- package/out/util/sandboxes-container.js +2 -4
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# @forge/tunnel
|
|
2
2
|
|
|
3
|
+
## 5.0.1-next.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- eb06eca: Break more dependencies between SDK and runtime
|
|
8
|
+
- Updated dependencies [eb06eca]
|
|
9
|
+
- @forge/bundler@4.15.10-next.4
|
|
10
|
+
- @forge/runtime@5.6.1-next.1
|
|
11
|
+
|
|
12
|
+
## 5.0.1-next.4
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- Updated dependencies [83e1cd7]
|
|
17
|
+
- @forge/cli-shared@4.0.0-next.3
|
|
18
|
+
- @forge/bundler@4.15.10-next.3
|
|
19
|
+
|
|
3
20
|
## 5.0.1-next.3
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
|
@@ -10,15 +10,16 @@ const runtime_1 = require("@forge/runtime");
|
|
|
10
10
|
const util_1 = require("../../util");
|
|
11
11
|
exports.MEMORY_LIMIT = 256;
|
|
12
12
|
class LocalFunctionHost {
|
|
13
|
+
configFile;
|
|
14
|
+
logger;
|
|
15
|
+
snapshot;
|
|
16
|
+
createSandbox;
|
|
17
|
+
snapshotLogs = [];
|
|
13
18
|
constructor(configFile, logger, snapshot, createSandbox) {
|
|
14
19
|
this.configFile = configFile;
|
|
15
20
|
this.logger = logger;
|
|
16
21
|
this.snapshot = snapshot;
|
|
17
22
|
this.createSandbox = createSandbox;
|
|
18
|
-
this.snapshotLogs = [];
|
|
19
|
-
this.onRuntimeLog = (event) => {
|
|
20
|
-
this.logger.info((0, util_1.formatRuntimeLog)(event));
|
|
21
|
-
};
|
|
22
23
|
}
|
|
23
24
|
async generateBundleFiles(bundle, withSnapshot) {
|
|
24
25
|
await fs_1.promises.mkdir((0, path_1.dirname)(bundle.bundleFilePath), { recursive: true });
|
|
@@ -48,13 +49,12 @@ class LocalFunctionHost {
|
|
|
48
49
|
this.snapshotLogs = [];
|
|
49
50
|
}
|
|
50
51
|
const bundles = Object.keys(bundledCode.output).map((bundlePath) => {
|
|
51
|
-
var _a;
|
|
52
52
|
const sourceMapPath = `${bundlePath}.map`;
|
|
53
53
|
return {
|
|
54
54
|
bundleFilePath: (0, path_1.resolve)(directory, bundlePath),
|
|
55
55
|
bundleFileContent: bundledCode.output[bundlePath],
|
|
56
56
|
bundleFileSourceMapPath: (0, path_1.resolve)(directory, sourceMapPath),
|
|
57
|
-
bundleFileSourceMap:
|
|
57
|
+
bundleFileSourceMap: bundledCode.sourceMap?.[sourceMapPath]
|
|
58
58
|
};
|
|
59
59
|
});
|
|
60
60
|
const manifestFilePath = (0, path_1.resolve)(directory, cli_shared_1.manifestFileName);
|
|
@@ -84,6 +84,9 @@ class LocalFunctionHost {
|
|
|
84
84
|
async stopWatching() {
|
|
85
85
|
runtime_1.StaticInvocationEventEmitter.removeAllListeners();
|
|
86
86
|
}
|
|
87
|
+
onRuntimeLog = (event) => {
|
|
88
|
+
this.logger.info((0, util_1.formatRuntimeLog)(event));
|
|
89
|
+
};
|
|
87
90
|
async initializeSandboxes(srcPath, tunnelOptions) {
|
|
88
91
|
try {
|
|
89
92
|
const handlers = await this.configFile.getAppHandlers();
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MultiCompilerWatcher = void 0;
|
|
4
4
|
class MultiCompilerWatcher {
|
|
5
|
+
servers;
|
|
5
6
|
constructor(servers) {
|
|
6
7
|
this.servers = servers;
|
|
7
8
|
}
|
|
@@ -14,9 +15,18 @@ class MultiCompilerWatcher {
|
|
|
14
15
|
output: {}
|
|
15
16
|
};
|
|
16
17
|
for (const result of results) {
|
|
17
|
-
multiResult.output =
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
multiResult.output = {
|
|
19
|
+
...multiResult.output,
|
|
20
|
+
...result.output
|
|
21
|
+
};
|
|
22
|
+
multiResult.sourceMap = {
|
|
23
|
+
...multiResult.sourceMap,
|
|
24
|
+
...result.sourceMap
|
|
25
|
+
};
|
|
26
|
+
multiResult.metadata = {
|
|
27
|
+
...multiResult.metadata,
|
|
28
|
+
...result.metadata
|
|
29
|
+
};
|
|
20
30
|
}
|
|
21
31
|
return multiResult;
|
|
22
32
|
}
|
|
@@ -7,55 +7,9 @@ const bundler_1 = require("@forge/bundler");
|
|
|
7
7
|
const cli_shared_1 = require("@forge/cli-shared");
|
|
8
8
|
const multi_compiler_watcher_1 = require("./multi-compiler-watcher");
|
|
9
9
|
class TunnelInteractor {
|
|
10
|
+
logger;
|
|
10
11
|
constructor(logger) {
|
|
11
12
|
this.logger = logger;
|
|
12
|
-
this.watchApp = async (startTunnelResult, tunnelOptions = {}) => {
|
|
13
|
-
const { localPort, inspectorAddress, reloadSandboxes, devServers } = startTunnelResult;
|
|
14
|
-
if (inspectorAddress) {
|
|
15
|
-
this.logger.info(cli_shared_1.Text.tunnel.startedInspector(inspectorAddress));
|
|
16
|
-
}
|
|
17
|
-
const onBundlingStart = async () => {
|
|
18
|
-
try {
|
|
19
|
-
this.logger.info('');
|
|
20
|
-
this.logger.info(cli_shared_1.Text.bundle.detectedChanges);
|
|
21
|
-
await (0, bundler_1.runLinter)();
|
|
22
|
-
this.logger.info(cli_shared_1.Text.tunnel.preBundleTask(cli_shared_1.Text.tunnel.bundlingHeader));
|
|
23
|
-
}
|
|
24
|
-
catch (err) {
|
|
25
|
-
throw err;
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
const onBundlingFinish = async (err, output) => {
|
|
29
|
-
if (err) {
|
|
30
|
-
this.logger.error(err);
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
if (output) {
|
|
34
|
-
await reloadSandboxes(output, tunnelOptions);
|
|
35
|
-
}
|
|
36
|
-
this.logger.info('');
|
|
37
|
-
this.logger.info(cli_shared_1.Text.tunnel.startedServer(localPort, this.logger.debugEnabled) + '\n');
|
|
38
|
-
};
|
|
39
|
-
if (devServers.length > 0) {
|
|
40
|
-
const multiCompiler = new multi_compiler_watcher_1.MultiCompilerWatcher(devServers);
|
|
41
|
-
await (0, bundler_1.runLinter)();
|
|
42
|
-
this.logger.info(cli_shared_1.Text.tunnel.preBundleTask(cli_shared_1.Text.tunnel.bundlingHeader));
|
|
43
|
-
try {
|
|
44
|
-
const output = await multiCompiler.compileAndWatch({
|
|
45
|
-
onChange: {
|
|
46
|
-
onBuildWillStart: onBundlingStart,
|
|
47
|
-
onBuildFinished: onBundlingFinish
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
await reloadSandboxes(output, tunnelOptions);
|
|
51
|
-
this.logger.info('');
|
|
52
|
-
this.logger.info(cli_shared_1.Text.tunnel.startedServer(localPort, this.logger.debugEnabled) + '\n');
|
|
53
|
-
}
|
|
54
|
-
catch (_) {
|
|
55
|
-
}
|
|
56
|
-
return multiCompiler;
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
13
|
}
|
|
60
14
|
handleUserExitEvent(stopFunction, bundleMonitor) {
|
|
61
15
|
return new Promise((resolve, reject) => {
|
|
@@ -88,5 +42,52 @@ class TunnelInteractor {
|
|
|
88
42
|
process.on('SIGTERM', tunnelCleanupListener);
|
|
89
43
|
});
|
|
90
44
|
}
|
|
45
|
+
watchApp = async (startTunnelResult, tunnelOptions = {}) => {
|
|
46
|
+
const { localPort, inspectorAddress, reloadSandboxes, devServers } = startTunnelResult;
|
|
47
|
+
if (inspectorAddress) {
|
|
48
|
+
this.logger.info(cli_shared_1.Text.tunnel.startedInspector(inspectorAddress));
|
|
49
|
+
}
|
|
50
|
+
const onBundlingStart = async () => {
|
|
51
|
+
try {
|
|
52
|
+
this.logger.info('');
|
|
53
|
+
this.logger.info(cli_shared_1.Text.bundle.detectedChanges);
|
|
54
|
+
await (0, bundler_1.runLinter)();
|
|
55
|
+
this.logger.info(cli_shared_1.Text.tunnel.preBundleTask(cli_shared_1.Text.tunnel.bundlingHeader));
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
throw err;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const onBundlingFinish = async (err, output) => {
|
|
62
|
+
if (err) {
|
|
63
|
+
this.logger.error(err);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (output) {
|
|
67
|
+
await reloadSandboxes(output, tunnelOptions);
|
|
68
|
+
}
|
|
69
|
+
this.logger.info('');
|
|
70
|
+
this.logger.info(cli_shared_1.Text.tunnel.startedServer(localPort, this.logger.debugEnabled) + '\n');
|
|
71
|
+
};
|
|
72
|
+
if (devServers.length > 0) {
|
|
73
|
+
const multiCompiler = new multi_compiler_watcher_1.MultiCompilerWatcher(devServers);
|
|
74
|
+
await (0, bundler_1.runLinter)();
|
|
75
|
+
this.logger.info(cli_shared_1.Text.tunnel.preBundleTask(cli_shared_1.Text.tunnel.bundlingHeader));
|
|
76
|
+
try {
|
|
77
|
+
const output = await multiCompiler.compileAndWatch({
|
|
78
|
+
onChange: {
|
|
79
|
+
onBuildWillStart: onBundlingStart,
|
|
80
|
+
onBuildFinished: onBundlingFinish
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
await reloadSandboxes(output, tunnelOptions);
|
|
84
|
+
this.logger.info('');
|
|
85
|
+
this.logger.info(cli_shared_1.Text.tunnel.startedServer(localPort, this.logger.debugEnabled) + '\n');
|
|
86
|
+
}
|
|
87
|
+
catch (_) {
|
|
88
|
+
}
|
|
89
|
+
return multiCompiler;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
91
92
|
}
|
|
92
93
|
exports.TunnelInteractor = TunnelInteractor;
|
|
@@ -8,6 +8,16 @@ const node_cache_1 = tslib_1.__importDefault(require("node-cache"));
|
|
|
8
8
|
const servers_1 = require("../servers");
|
|
9
9
|
const index_1 = require("../index");
|
|
10
10
|
class StartTunnelCommand {
|
|
11
|
+
getAppConfig;
|
|
12
|
+
devServer;
|
|
13
|
+
tunnelFactory;
|
|
14
|
+
tunnelClient;
|
|
15
|
+
functionHost;
|
|
16
|
+
inspector;
|
|
17
|
+
logger;
|
|
18
|
+
configFile;
|
|
19
|
+
tunnelServers = {};
|
|
20
|
+
cspReporterServer;
|
|
11
21
|
constructor(getAppConfig, devServer, tunnelFactory, tunnelClient, functionHost, inspector, logger, configFile) {
|
|
12
22
|
this.getAppConfig = getAppConfig;
|
|
13
23
|
this.devServer = devServer;
|
|
@@ -17,44 +27,51 @@ class StartTunnelCommand {
|
|
|
17
27
|
this.inspector = inspector;
|
|
18
28
|
this.logger = logger;
|
|
19
29
|
this.configFile = configFile;
|
|
20
|
-
this.tunnelServers = {};
|
|
21
|
-
this.stopServices = async (appId, environmentKey) => {
|
|
22
|
-
var _a;
|
|
23
|
-
await Promise.all([
|
|
24
|
-
this.functionHost.stopWatching(),
|
|
25
|
-
this.tunnelClient.unregisterTunnels(appId, environmentKey),
|
|
26
|
-
this.tunnelFactory.closeTunnel(),
|
|
27
|
-
this.devServer.stop(),
|
|
28
|
-
this.inspector.stopServer(),
|
|
29
|
-
...Object.values(this.tunnelServers).map((server) => server.stop()),
|
|
30
|
-
(_a = this.cspReporterServer) === null || _a === void 0 ? void 0 : _a.stop()
|
|
31
|
-
]);
|
|
32
|
-
};
|
|
33
|
-
this.startFaaSTunnelServer = async ({ port, tunnelConfigPath }) => {
|
|
34
|
-
const { permissions = {}, remotes = [] } = await this.configFile.readConfig();
|
|
35
|
-
const serverInfo = await this.devServer.start(port, permissions, remotes);
|
|
36
|
-
const faasTunnelUrl = await this.tunnelFactory.establishTunnel({ port: serverInfo.port, tunnelConfigPath });
|
|
37
|
-
return Object.assign(Object.assign({}, serverInfo), { tunnelUrl: faasTunnelUrl });
|
|
38
|
-
};
|
|
39
|
-
this.startResourceBasedTunnelsServers = async (resourceDetails, options) => {
|
|
40
|
-
var _a, _b, _c;
|
|
41
|
-
const portMap = (_a = options.resourcePortMap) !== null && _a !== void 0 ? _a : JSON.parse((_b = process.env.RESOURCE_PORT_MAP) !== null && _b !== void 0 ? _b : '{}');
|
|
42
|
-
const { permissions = {}, remotes = [] } = await this.configFile.readConfig();
|
|
43
|
-
const cspReporterPort = parseInt((_c = process.env.CSP_REPORTER_PORT) !== null && _c !== void 0 ? _c : '4000', 10);
|
|
44
|
-
if (resourceDetails.length === 0)
|
|
45
|
-
return [];
|
|
46
|
-
this.cspReporterServer = new servers_1.CspReporterServer(cspReporterPort, this.logger, new node_cache_1.default());
|
|
47
|
-
await this.cspReporterServer.start();
|
|
48
|
-
return await Promise.all(resourceDetails.map(async (rd) => {
|
|
49
|
-
const { key, resourceType } = rd;
|
|
50
|
-
const port = portMap[key];
|
|
51
|
-
const tunnelServer = resourceType === 'nativeUI' ? servers_1.NativeUITunnelServer : servers_1.CustomUITunnelServer;
|
|
52
|
-
this.tunnelServers[key] = new tunnelServer(Object.assign(Object.assign({}, rd), { port, host: options.host, logger: this.logger, cspReporterServerPort: cspReporterPort, permissions,
|
|
53
|
-
remotes }));
|
|
54
|
-
return this.tunnelServers[key].start();
|
|
55
|
-
}));
|
|
56
|
-
};
|
|
57
30
|
}
|
|
31
|
+
stopServices = async (appId, environmentKey) => {
|
|
32
|
+
await Promise.all([
|
|
33
|
+
this.functionHost.stopWatching(),
|
|
34
|
+
this.tunnelClient.unregisterTunnels(appId, environmentKey),
|
|
35
|
+
this.tunnelFactory.closeTunnel(),
|
|
36
|
+
this.devServer.stop(),
|
|
37
|
+
this.inspector.stopServer(),
|
|
38
|
+
...Object.values(this.tunnelServers).map((server) => server.stop()),
|
|
39
|
+
this.cspReporterServer?.stop()
|
|
40
|
+
]);
|
|
41
|
+
};
|
|
42
|
+
startFaaSTunnelServer = async ({ port, tunnelConfigPath }) => {
|
|
43
|
+
const { permissions = {}, remotes = [] } = await this.configFile.readConfig();
|
|
44
|
+
const serverInfo = await this.devServer.start(port, permissions, remotes);
|
|
45
|
+
const faasTunnelUrl = await this.tunnelFactory.establishTunnel({ port: serverInfo.port, tunnelConfigPath });
|
|
46
|
+
return {
|
|
47
|
+
...serverInfo,
|
|
48
|
+
tunnelUrl: faasTunnelUrl
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
startResourceBasedTunnelsServers = async (resourceDetails, options) => {
|
|
52
|
+
const portMap = options.resourcePortMap ?? JSON.parse(process.env.RESOURCE_PORT_MAP ?? '{}');
|
|
53
|
+
const { permissions = {}, remotes = [] } = await this.configFile.readConfig();
|
|
54
|
+
const cspReporterPort = parseInt(process.env.CSP_REPORTER_PORT ?? '4000', 10);
|
|
55
|
+
if (resourceDetails.length === 0)
|
|
56
|
+
return [];
|
|
57
|
+
this.cspReporterServer = new servers_1.CspReporterServer(cspReporterPort, this.logger, new node_cache_1.default());
|
|
58
|
+
await this.cspReporterServer.start();
|
|
59
|
+
return await Promise.all(resourceDetails.map(async (rd) => {
|
|
60
|
+
const { key, resourceType } = rd;
|
|
61
|
+
const port = portMap[key];
|
|
62
|
+
const tunnelServer = resourceType === 'nativeUI' ? servers_1.NativeUITunnelServer : servers_1.CustomUITunnelServer;
|
|
63
|
+
this.tunnelServers[key] = new tunnelServer({
|
|
64
|
+
...rd,
|
|
65
|
+
port,
|
|
66
|
+
host: options.host,
|
|
67
|
+
logger: this.logger,
|
|
68
|
+
cspReporterServerPort: cspReporterPort,
|
|
69
|
+
permissions,
|
|
70
|
+
remotes
|
|
71
|
+
});
|
|
72
|
+
return this.tunnelServers[key].start();
|
|
73
|
+
}));
|
|
74
|
+
};
|
|
58
75
|
async execute(options) {
|
|
59
76
|
const { id: appId } = await this.getAppConfig();
|
|
60
77
|
const { port, environmentKey } = options;
|
|
@@ -99,7 +116,7 @@ class StartTunnelCommand {
|
|
|
99
116
|
try {
|
|
100
117
|
await this.stopServices(appId, environmentKey);
|
|
101
118
|
}
|
|
102
|
-
catch
|
|
119
|
+
catch { }
|
|
103
120
|
throw e;
|
|
104
121
|
}
|
|
105
122
|
}
|
package/out/index.d.ts
CHANGED
package/out/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc,QAEnB,CAAC;AAET,wBAAgB,kBAAkB,YAEjC;AAED,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc,QAEnB,CAAC;AAET,wBAAgB,kBAAkB,YAEjC;AAED,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC"}
|
package/out/index.js
CHANGED
|
@@ -14,3 +14,4 @@ tslib_1.__exportStar(require("./servers"), exports);
|
|
|
14
14
|
tslib_1.__exportStar(require("./command"), exports);
|
|
15
15
|
tslib_1.__exportStar(require("./graphql"), exports);
|
|
16
16
|
tslib_1.__exportStar(require("./util"), exports);
|
|
17
|
+
tslib_1.__exportStar(require("./sandbox"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sandbox/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { XenInvocationRequest, LimitsTracker, InvocationResult, Sandbox, SandboxConfig, Inspector } from '@forge/runtime';
|
|
2
|
+
export declare class NodeSandbox implements Sandbox {
|
|
3
|
+
readonly name: string;
|
|
4
|
+
private readonly process;
|
|
5
|
+
private readonly callbacks;
|
|
6
|
+
constructor({ appPath, modName, handler, debugPort }: SandboxConfig);
|
|
7
|
+
private handleOutput;
|
|
8
|
+
execute(xenInvocationRequest: XenInvocationRequest, invocationLimits: LimitsTracker, inspector?: Inspector | undefined): Promise<InvocationResult>;
|
|
9
|
+
stop(): void;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=node-sandbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-sandbox.d.ts","sourceRoot":"","sources":["../../src/sandbox/node-sandbox.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,gBAAgB,EAChB,OAAO,EACP,aAAa,EACb,SAAS,EAIV,MAAM,gBAAgB,CAAC;AAIxB,qBAAa,WAAY,YAAW,OAAO;IACzC,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAe;IACvC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkD;gBAEhE,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,EAAE,aAAa;IA2BnE,OAAO,CAAC,YAAY;IAOd,OAAO,CACX,oBAAoB,EAAE,oBAAoB,EAC1C,gBAAgB,EAAE,aAAa,EAC/B,SAAS,CAAC,EAAE,SAAS,GAAG,SAAS,GAChC,OAAO,CAAC,gBAAgB,CAAC;IAmB5B,IAAI,IAAI,IAAI;CAGb"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NodeSandbox = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const child_process_1 = require("child_process");
|
|
6
|
+
const path_1 = require("path");
|
|
7
|
+
const readline_1 = tslib_1.__importDefault(require("readline"));
|
|
8
|
+
const uuid_1 = require("uuid");
|
|
9
|
+
const runtime_1 = require("@forge/runtime");
|
|
10
|
+
const RUNNER = (0, path_1.join)(__dirname, '..', '..', 'out', 'sandbox', 'sandbox-runner.js');
|
|
11
|
+
class NodeSandbox {
|
|
12
|
+
name;
|
|
13
|
+
process;
|
|
14
|
+
callbacks;
|
|
15
|
+
constructor({ appPath, modName, handler, debugPort }) {
|
|
16
|
+
this.name = `${modName}.${handler}`;
|
|
17
|
+
const fileName = `${appPath}/${modName}.cjs`;
|
|
18
|
+
this.callbacks = new Map();
|
|
19
|
+
this.process = (0, child_process_1.fork)(RUNNER, [fileName, handler], {
|
|
20
|
+
stdio: ['ignore', 'pipe', 2, 'ipc'],
|
|
21
|
+
env: {
|
|
22
|
+
_HANDLER: this.name
|
|
23
|
+
},
|
|
24
|
+
execArgv: debugPort ? [`--inspect=0.0.0.0:${debugPort}`] : undefined
|
|
25
|
+
});
|
|
26
|
+
readline_1.default.createInterface(this.process.stdout).on('line', (line) => {
|
|
27
|
+
const message = JSON.parse(line);
|
|
28
|
+
this.handleOutput(message);
|
|
29
|
+
});
|
|
30
|
+
this.process.on('message', (message) => {
|
|
31
|
+
const requestId = message.requestId;
|
|
32
|
+
const result = message.result;
|
|
33
|
+
this.callbacks.get(requestId)?.(result);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
handleOutput(output) {
|
|
37
|
+
if (output.invocationId) {
|
|
38
|
+
const p3LogEvent = output;
|
|
39
|
+
runtime_1.StaticInvocationEventEmitter.emit(runtime_1.EVENT_P3_LOG, p3LogEvent);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async execute(xenInvocationRequest, invocationLimits, inspector) {
|
|
43
|
+
const lambdaEvent = {
|
|
44
|
+
_meta: xenInvocationRequest.__deprecatedGetMeta(),
|
|
45
|
+
body: xenInvocationRequest.getBody(),
|
|
46
|
+
variables: xenInvocationRequest.getUserVariables()
|
|
47
|
+
};
|
|
48
|
+
const requestId = (0, uuid_1.v4)();
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
this.callbacks.set(requestId, (result) => {
|
|
51
|
+
this.callbacks.delete(requestId);
|
|
52
|
+
resolve(result);
|
|
53
|
+
});
|
|
54
|
+
const lambdaContext = { awsRequestId: requestId };
|
|
55
|
+
this.process.send({ lambdaEvent, lambdaContext });
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
stop() {
|
|
59
|
+
this.process.kill();
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.NodeSandbox = NodeSandbox;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox-runner.d.ts","sourceRoot":"","sources":["../../src/sandbox/sandbox-runner.ts"],"names":[],"mappings":"AAAA,QAAA,MAAO,WAAW,UAAE,WAAW,UAAE,QAAQ,UAAE,WAAW,QAAgB,CAAC;AAMvE,QAAA,MAAM,OAAO,KAAiC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const [_nodeBinary, _thisScript, fileName, handlerName] = process.argv;
|
|
3
|
+
global.__forge_tunnel__ = true;
|
|
4
|
+
const handler = require(fileName)[handlerName];
|
|
5
|
+
process.on('message', async ({ lambdaEvent, lambdaContext }) => {
|
|
6
|
+
const requestId = lambdaContext.awsRequestId;
|
|
7
|
+
const result = await handler(lambdaEvent, lambdaContext);
|
|
8
|
+
process.send?.({ requestId, result });
|
|
9
|
+
});
|
|
@@ -5,6 +5,12 @@ const tslib_1 = require("tslib");
|
|
|
5
5
|
const express_1 = tslib_1.__importDefault(require("express"));
|
|
6
6
|
const cli_shared_1 = require("@forge/cli-shared");
|
|
7
7
|
class CspReporterServer {
|
|
8
|
+
port;
|
|
9
|
+
logger;
|
|
10
|
+
cache;
|
|
11
|
+
app;
|
|
12
|
+
server;
|
|
13
|
+
static TTL_IN_SECONDS = 30;
|
|
8
14
|
constructor(port, logger, cache) {
|
|
9
15
|
this.port = port;
|
|
10
16
|
this.logger = logger;
|
|
@@ -35,10 +41,8 @@ class CspReporterServer {
|
|
|
35
41
|
}
|
|
36
42
|
async stop() {
|
|
37
43
|
return new Promise((resolve, reject) => {
|
|
38
|
-
|
|
39
|
-
(_a = this.server) === null || _a === void 0 ? void 0 : _a.close((err) => (err ? reject(err) : resolve()));
|
|
44
|
+
this.server?.close((err) => (err ? reject(err) : resolve()));
|
|
40
45
|
});
|
|
41
46
|
}
|
|
42
47
|
}
|
|
43
48
|
exports.CspReporterServer = CspReporterServer;
|
|
44
|
-
CspReporterServer.TTL_IN_SECONDS = 30;
|
|
@@ -14,15 +14,19 @@ var ConnectionErrorCode;
|
|
|
14
14
|
ConnectionErrorCode["REFUSED"] = "ECONNREFUSED";
|
|
15
15
|
})(ConnectionErrorCode || (ConnectionErrorCode = {}));
|
|
16
16
|
class CustomUITunnelServer extends resource_tunnel_server_1.ResourceTunnelServer {
|
|
17
|
+
tunnelArgs;
|
|
18
|
+
app;
|
|
19
|
+
server;
|
|
20
|
+
proxy;
|
|
21
|
+
socket;
|
|
17
22
|
constructor(tunnelArgs) {
|
|
18
|
-
var _a, _b;
|
|
19
23
|
super(tunnelArgs);
|
|
20
24
|
this.tunnelArgs = tunnelArgs;
|
|
21
25
|
const { tunnel, permissions, remotes } = tunnelArgs;
|
|
22
26
|
this.app = (0, express_1.default)();
|
|
23
27
|
this.app.use(this.getCustomUIHtmlTransformMiddleware(permissions, remotes));
|
|
24
28
|
if (tunnel) {
|
|
25
|
-
|
|
29
|
+
net_1.default.setDefaultAutoSelectFamily?.(true);
|
|
26
30
|
const { port: tunnelPort } = tunnel;
|
|
27
31
|
this.proxy = (0, http_proxy_middleware_1.createProxyMiddleware)({
|
|
28
32
|
target: `http://${this.tunnelArgs.host}:${tunnelPort}`,
|
|
@@ -80,7 +84,7 @@ class CustomUITunnelServer extends resource_tunnel_server_1.ResourceTunnelServer
|
|
|
80
84
|
return this.app;
|
|
81
85
|
}
|
|
82
86
|
handleProxyDestinationNotStarted(err, reqUrl, res, tunnelPort) {
|
|
83
|
-
if (
|
|
87
|
+
if (err?.code !== ConnectionErrorCode.REFUSED || (reqUrl !== '/' && reqUrl !== 'index.html')) {
|
|
84
88
|
this.logger.error(err);
|
|
85
89
|
return;
|
|
86
90
|
}
|
|
@@ -91,9 +95,8 @@ class CustomUITunnelServer extends resource_tunnel_server_1.ResourceTunnelServer
|
|
|
91
95
|
res.end(cli_shared_1.Text.tunnel.error.serverNotStartedOnPort(tunnelPort));
|
|
92
96
|
}
|
|
93
97
|
handleWebsocketUpgrade(req, socket, head) {
|
|
94
|
-
var _a;
|
|
95
98
|
this.socket = socket;
|
|
96
|
-
if (
|
|
99
|
+
if (this.proxy?.upgrade) {
|
|
97
100
|
return this.proxy.upgrade(req, socket, head);
|
|
98
101
|
}
|
|
99
102
|
}
|
|
@@ -19,44 +19,19 @@ async function stopServer(server) {
|
|
|
19
19
|
}
|
|
20
20
|
exports.stopServer = stopServer;
|
|
21
21
|
class LocalDevelopmentServer {
|
|
22
|
+
invocationService;
|
|
23
|
+
logger;
|
|
24
|
+
configFile;
|
|
25
|
+
fileSystemReader;
|
|
26
|
+
app;
|
|
27
|
+
httpServer;
|
|
28
|
+
permissions;
|
|
29
|
+
remotes;
|
|
22
30
|
constructor(invocationService, logger, configFile, fileSystemReader) {
|
|
23
31
|
this.invocationService = invocationService;
|
|
24
32
|
this.logger = logger;
|
|
25
33
|
this.configFile = configFile;
|
|
26
34
|
this.fileSystemReader = fileSystemReader;
|
|
27
|
-
this.handleInvocation = async (req, res) => {
|
|
28
|
-
var _a, _b, _c, _d, _e, _f;
|
|
29
|
-
const request = req.body;
|
|
30
|
-
const envVars = (0, runtime_1.getUserVars)();
|
|
31
|
-
(_a = request.variables) === null || _a === void 0 ? void 0 : _a.forEach((item) => {
|
|
32
|
-
if (!envVars.find((i) => i.key === item.key)) {
|
|
33
|
-
envVars.push(item);
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
request.variables = [...envVars].sort((a, b) => a.key.localeCompare(b.key));
|
|
37
|
-
const allowList = (_f = (_e = (_d = (_c = (_b = this.permissions) === null || _b === void 0 ? void 0 : _b.external) === null || _c === void 0 ? void 0 : _c.fetch) === null || _d === void 0 ? void 0 : _d.backend) === null || _e === void 0 ? void 0 : _e.map((item) => {
|
|
38
|
-
var _a, _b;
|
|
39
|
-
if (typeof item === 'string')
|
|
40
|
-
return item;
|
|
41
|
-
return (_b = (_a = this.remotes) === null || _a === void 0 ? void 0 : _a.find((remote) => remote.key === item.remote)) === null || _b === void 0 ? void 0 : _b.baseUrl;
|
|
42
|
-
}).filter((item) => typeof item === 'string')) !== null && _f !== void 0 ? _f : undefined;
|
|
43
|
-
request._meta = Object.assign(Object.assign({}, request._meta), { fetchAllowList: allowList });
|
|
44
|
-
try {
|
|
45
|
-
const invokeResults = await this.invocationService.invoke(request.handler, request);
|
|
46
|
-
if ((await this.configFile.runtimeType()) === cli_shared_1.RuntimeType.nodejs && !invokeResults.success) {
|
|
47
|
-
return res.status(500).send(invokeResults.error);
|
|
48
|
-
}
|
|
49
|
-
res.json(invokeResults);
|
|
50
|
-
}
|
|
51
|
-
catch (error) {
|
|
52
|
-
try {
|
|
53
|
-
res.status(500).send((0, util_1.toLambdaError)(error));
|
|
54
|
-
}
|
|
55
|
-
catch (e) {
|
|
56
|
-
this.logger.error(e);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
35
|
this.app = (0, express_1.default)();
|
|
61
36
|
this.app.use(express_1.default.json({ limit: '6mb' }));
|
|
62
37
|
this.app.post(`/:fnKey`, this.handleInvocation);
|
|
@@ -121,5 +96,41 @@ class LocalDevelopmentServer {
|
|
|
121
96
|
getApp() {
|
|
122
97
|
return this.app;
|
|
123
98
|
}
|
|
99
|
+
handleInvocation = async (req, res) => {
|
|
100
|
+
const request = req.body;
|
|
101
|
+
const envVars = (0, runtime_1.getUserVars)();
|
|
102
|
+
request.variables?.forEach((item) => {
|
|
103
|
+
if (!envVars.find((i) => i.key === item.key)) {
|
|
104
|
+
envVars.push(item);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
request.variables = [...envVars].sort((a, b) => a.key.localeCompare(b.key));
|
|
108
|
+
const allowList = this.permissions?.external?.fetch?.backend
|
|
109
|
+
?.map((item) => {
|
|
110
|
+
if (typeof item === 'string')
|
|
111
|
+
return item;
|
|
112
|
+
return this.remotes?.find((remote) => remote.key === item.remote)?.baseUrl;
|
|
113
|
+
})
|
|
114
|
+
.filter((item) => typeof item === 'string') ?? undefined;
|
|
115
|
+
request._meta = {
|
|
116
|
+
...request._meta,
|
|
117
|
+
fetchAllowList: allowList
|
|
118
|
+
};
|
|
119
|
+
try {
|
|
120
|
+
const invokeResults = await this.invocationService.invoke(request.handler, request);
|
|
121
|
+
if ((await this.configFile.runtimeType()) === cli_shared_1.RuntimeType.nodejs && !invokeResults.success) {
|
|
122
|
+
return res.status(500).send(invokeResults.error);
|
|
123
|
+
}
|
|
124
|
+
res.json(invokeResults);
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
try {
|
|
128
|
+
res.status(500).send((0, util_1.toLambdaError)(error));
|
|
129
|
+
}
|
|
130
|
+
catch (e) {
|
|
131
|
+
this.logger.error(e);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
};
|
|
124
135
|
}
|
|
125
136
|
exports.LocalDevelopmentServer = LocalDevelopmentServer;
|
|
@@ -8,19 +8,26 @@ const resource_tunnel_server_1 = require("./resource-tunnel-server");
|
|
|
8
8
|
const cli_shared_1 = require("@forge/cli-shared");
|
|
9
9
|
const url_1 = require("url");
|
|
10
10
|
class NativeUITunnelServer extends resource_tunnel_server_1.ResourceTunnelServer {
|
|
11
|
+
tunnelArgs;
|
|
12
|
+
server;
|
|
11
13
|
constructor(tunnelArgs) {
|
|
12
14
|
super(tunnelArgs);
|
|
13
15
|
this.tunnelArgs = tunnelArgs;
|
|
14
16
|
const { key, path, port, permissions, remotes } = tunnelArgs;
|
|
15
17
|
const entrypoint = { name: key, path, functions: [] };
|
|
16
18
|
const config = (0, bundler_1.getNativeUiBuildConfig)([entrypoint]);
|
|
17
|
-
const compiler = (0, bundler_1.getCompiler)(
|
|
19
|
+
const compiler = (0, bundler_1.getCompiler)({
|
|
20
|
+
...config,
|
|
21
|
+
infrastructureLogging: {
|
|
18
22
|
level: 'error'
|
|
19
|
-
},
|
|
23
|
+
},
|
|
24
|
+
stats: 'errors-only',
|
|
25
|
+
watchOptions: {
|
|
20
26
|
aggregateTimeout: 200,
|
|
21
27
|
poll: 1000,
|
|
22
28
|
ignored: '**/node_modules'
|
|
23
|
-
}
|
|
29
|
+
}
|
|
30
|
+
});
|
|
24
31
|
this.server = new webpack_dev_server_1.default({
|
|
25
32
|
port,
|
|
26
33
|
host: process.env.FORGE_DEV_TUNNEL ? 'localhost' : '0.0.0.0',
|
|
@@ -5,31 +5,12 @@ const cli_shared_1 = require("@forge/cli-shared");
|
|
|
5
5
|
const csp_1 = require("@forge/csp");
|
|
6
6
|
const express_intercept_1 = require("express-intercept");
|
|
7
7
|
class ResourceTunnelServer {
|
|
8
|
+
port;
|
|
9
|
+
key;
|
|
10
|
+
path;
|
|
11
|
+
logger;
|
|
12
|
+
cspReporterServerPort;
|
|
8
13
|
constructor({ port, key, path, cspReporterServerPort, logger }) {
|
|
9
|
-
this.getCspHeader = (existingCsp) => new csp_1.CSPInjectionService()
|
|
10
|
-
.getInjectableCSP({
|
|
11
|
-
existingCSPDetails: existingCsp,
|
|
12
|
-
microsEnv: (0, cli_shared_1.getEnvironment)(cli_shared_1.CDNEnvironments),
|
|
13
|
-
tunnelCSPReporterUri: `http://localhost:${this.cspReporterServerPort}`
|
|
14
|
-
})
|
|
15
|
-
.join('; ');
|
|
16
|
-
this.injectGlobalBridgeScript = (htmlContent) => new cli_shared_1.BridgeScriptService().injectBridgeCore(htmlContent, () => {
|
|
17
|
-
throw new Error('Malformed HTML document');
|
|
18
|
-
});
|
|
19
|
-
this.injectIframeResizerScript = (htmlContent) => new cli_shared_1.IframeResizerScriptService().injectIframeResizer(htmlContent, () => {
|
|
20
|
-
throw new Error('Malformed HTML document');
|
|
21
|
-
});
|
|
22
|
-
this.getCustomUIHtmlTransformMiddleware = (permissions, remotes) => (0, express_intercept_1.responseHandler)()
|
|
23
|
-
.if((res) => /html/i.test(res.get('content-type')))
|
|
24
|
-
.replaceBuffer((body, _, res) => {
|
|
25
|
-
if (!res)
|
|
26
|
-
return body;
|
|
27
|
-
const htmlContentWithIframeResizerScript = this.injectIframeResizerScript(body);
|
|
28
|
-
const htmlContentWithBridgeScript = this.injectGlobalBridgeScript(htmlContentWithIframeResizerScript);
|
|
29
|
-
const cspDetails = new csp_1.CSPProcessingService({ info: () => { } }).getCspDetails(htmlContentWithBridgeScript, ResourceTunnelServer.transformPermissionsWithRemotes(permissions, remotes));
|
|
30
|
-
res.setHeader('Content-Security-Policy', this.getCspHeader(cspDetails));
|
|
31
|
-
return htmlContentWithBridgeScript;
|
|
32
|
-
});
|
|
33
14
|
this.port = port;
|
|
34
15
|
this.key = key;
|
|
35
16
|
this.path = path;
|
|
@@ -37,19 +18,43 @@ class ResourceTunnelServer {
|
|
|
37
18
|
this.cspReporterServerPort = cspReporterServerPort;
|
|
38
19
|
}
|
|
39
20
|
static transformPermissionsWithRemotes(permissions, remotes) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
var _a;
|
|
21
|
+
const client = permissions.external?.fetch?.client
|
|
22
|
+
?.map((item) => {
|
|
43
23
|
if (typeof item === 'string')
|
|
44
24
|
return item;
|
|
45
|
-
return
|
|
46
|
-
})
|
|
47
|
-
|
|
25
|
+
return remotes?.find((remote) => remote.key === item.remote)?.baseUrl;
|
|
26
|
+
})
|
|
27
|
+
.filter((item) => typeof item === 'string') ?? undefined;
|
|
28
|
+
return { ...permissions, external: { ...permissions.external, fetch: { ...permissions.external?.fetch, client } } };
|
|
48
29
|
}
|
|
49
30
|
logFileServed(reqUrl, textDecorator) {
|
|
50
31
|
if (reqUrl !== '/' && reqUrl !== '/index.html')
|
|
51
32
|
return;
|
|
52
33
|
this.logger.info(cli_shared_1.LogColor.trace(textDecorator('index.html')));
|
|
53
34
|
}
|
|
35
|
+
getCspHeader = (existingCsp) => new csp_1.CSPInjectionService()
|
|
36
|
+
.getInjectableCSP({
|
|
37
|
+
existingCSPDetails: existingCsp,
|
|
38
|
+
microsEnv: (0, cli_shared_1.getEnvironment)(cli_shared_1.CDNEnvironments),
|
|
39
|
+
tunnelCSPReporterUri: `http://localhost:${this.cspReporterServerPort}`
|
|
40
|
+
})
|
|
41
|
+
.join('; ');
|
|
42
|
+
injectGlobalBridgeScript = (htmlContent) => new cli_shared_1.BridgeScriptService().injectBridgeCore(htmlContent, () => {
|
|
43
|
+
throw new Error('Malformed HTML document');
|
|
44
|
+
});
|
|
45
|
+
injectIframeResizerScript = (htmlContent) => new cli_shared_1.IframeResizerScriptService().injectIframeResizer(htmlContent, () => {
|
|
46
|
+
throw new Error('Malformed HTML document');
|
|
47
|
+
});
|
|
48
|
+
getCustomUIHtmlTransformMiddleware = (permissions, remotes) => (0, express_intercept_1.responseHandler)()
|
|
49
|
+
.if((res) => /html/i.test(res.get('content-type')))
|
|
50
|
+
.replaceBuffer((body, _, res) => {
|
|
51
|
+
if (!res)
|
|
52
|
+
return body;
|
|
53
|
+
const htmlContentWithIframeResizerScript = this.injectIframeResizerScript(body);
|
|
54
|
+
const htmlContentWithBridgeScript = this.injectGlobalBridgeScript(htmlContentWithIframeResizerScript);
|
|
55
|
+
const cspDetails = new csp_1.CSPProcessingService({ info: () => { } }).getCspDetails(htmlContentWithBridgeScript, ResourceTunnelServer.transformPermissionsWithRemotes(permissions, remotes));
|
|
56
|
+
res.setHeader('Content-Security-Policy', this.getCspHeader(cspDetails));
|
|
57
|
+
return htmlContentWithBridgeScript;
|
|
58
|
+
});
|
|
54
59
|
}
|
|
55
60
|
exports.ResourceTunnelServer = ResourceTunnelServer;
|
|
@@ -34,6 +34,8 @@ class NgrokError extends cli_shared_1.BaseError {
|
|
|
34
34
|
}
|
|
35
35
|
exports.NgrokError = NgrokError;
|
|
36
36
|
class NgrokCreateTunnelService {
|
|
37
|
+
logger;
|
|
38
|
+
endpoint;
|
|
37
39
|
constructor(logger) {
|
|
38
40
|
this.logger = logger;
|
|
39
41
|
}
|
|
@@ -43,7 +45,7 @@ class NgrokCreateTunnelService {
|
|
|
43
45
|
try {
|
|
44
46
|
const options = {
|
|
45
47
|
addr: port,
|
|
46
|
-
configPath: tunnelConfigPath
|
|
48
|
+
configPath: tunnelConfigPath ?? defaultConfigPath,
|
|
47
49
|
onStatusChange: (status) => {
|
|
48
50
|
this.logger.debug(cli_shared_1.Text.tunnel.tunnelStatusChange(status));
|
|
49
51
|
},
|
|
@@ -54,7 +56,7 @@ class NgrokCreateTunnelService {
|
|
|
54
56
|
try {
|
|
55
57
|
ngrokErrorMessage = JSON.parse(ngrokErrorMessage);
|
|
56
58
|
}
|
|
57
|
-
catch
|
|
59
|
+
catch { }
|
|
58
60
|
}
|
|
59
61
|
this.logger.debug(data);
|
|
60
62
|
}
|
|
@@ -73,7 +75,7 @@ class NgrokCreateTunnelService {
|
|
|
73
75
|
await ngrok.disconnect();
|
|
74
76
|
await ngrok.kill();
|
|
75
77
|
}
|
|
76
|
-
catch
|
|
78
|
+
catch { }
|
|
77
79
|
this.endpoint = undefined;
|
|
78
80
|
}
|
|
79
81
|
}
|
|
@@ -8,13 +8,15 @@ const runtime_1 = require("@forge/runtime");
|
|
|
8
8
|
const cli_shared_1 = require("@forge/cli-shared");
|
|
9
9
|
const DEFAULT_INVOCATION_TIMEOUT = 25;
|
|
10
10
|
class LocalInvocationService {
|
|
11
|
+
configFile;
|
|
12
|
+
logger;
|
|
13
|
+
inspector;
|
|
11
14
|
constructor(configFile, logger, inspector) {
|
|
12
15
|
this.configFile = configFile;
|
|
13
16
|
this.logger = logger;
|
|
14
17
|
this.inspector = inspector;
|
|
15
18
|
}
|
|
16
19
|
async invoke(handler, request) {
|
|
17
|
-
var _a;
|
|
18
20
|
this.logger.info('');
|
|
19
21
|
this.logger.info((0, util_1.formatInvocation)(handler, request));
|
|
20
22
|
const sandbox = util_1.SandboxesContainer.get()[handler];
|
|
@@ -38,9 +40,9 @@ class LocalInvocationService {
|
|
|
38
40
|
variables.push({ key: 'FUNCTION_IS_SNAPSHOTTED', value: isSnapshotEnabled.toString(), secure: false });
|
|
39
41
|
}
|
|
40
42
|
const requestId = (0, util_1.getRequestId)(request, (0, uuid_1.v4)());
|
|
41
|
-
const timeout =
|
|
43
|
+
const timeout = request._meta.timeout ?? DEFAULT_INVOCATION_TIMEOUT;
|
|
42
44
|
const xenInvocationRequest = (0, runtime_1.xenInvocationRequestFactory)({
|
|
43
|
-
request:
|
|
45
|
+
request: { ...request, variables },
|
|
44
46
|
ctx: { requestId, traceId: requestId, timeout }
|
|
45
47
|
});
|
|
46
48
|
const invocationLimits = (0, runtime_1.perInvocationLimitsTrackerFactory)(xenInvocationRequest);
|
|
@@ -58,11 +60,11 @@ class LocalInvocationService {
|
|
|
58
60
|
LocalInvocationService.printMetrics(reportMetrics, metrics, this.logger);
|
|
59
61
|
return reportMetrics ? { body, metrics, success, error } : body;
|
|
60
62
|
}
|
|
63
|
+
static INTERNAL_METRICS = ['execute.setup-request-context', 'invoke.setup-isolate'];
|
|
64
|
+
static printMetrics = (shouldReportMetrics, metrics, logger) => {
|
|
65
|
+
if (shouldReportMetrics && metrics?.length) {
|
|
66
|
+
logger.debug(`Metrics: ${JSON.stringify(metrics.filter((m) => !LocalInvocationService.INTERNAL_METRICS.includes(m.name)), null, 2)}`);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
61
69
|
}
|
|
62
70
|
exports.LocalInvocationService = LocalInvocationService;
|
|
63
|
-
LocalInvocationService.INTERNAL_METRICS = ['execute.setup-request-context', 'invoke.setup-isolate'];
|
|
64
|
-
LocalInvocationService.printMetrics = (shouldReportMetrics, metrics, logger) => {
|
|
65
|
-
if (shouldReportMetrics && (metrics === null || metrics === void 0 ? void 0 : metrics.length)) {
|
|
66
|
-
logger.debug(`Metrics: ${JSON.stringify(metrics.filter((m) => !LocalInvocationService.INTERNAL_METRICS.includes(m.name)), null, 2)}`);
|
|
67
|
-
}
|
|
68
|
-
};
|
|
@@ -3,10 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.RegisterTunnelServiceImpl = void 0;
|
|
4
4
|
const ONE_DAY = 1000 * 60 * 60 * 24;
|
|
5
5
|
class RegisterTunnelServiceImpl {
|
|
6
|
+
tunnelClient;
|
|
6
7
|
constructor(tunnelClient) {
|
|
7
8
|
this.tunnelClient = tunnelClient;
|
|
8
9
|
this.keepAliveActive = true;
|
|
9
10
|
}
|
|
11
|
+
keepAliveHandler;
|
|
12
|
+
keepAliveActive;
|
|
10
13
|
async registerTunnels(appId, environmentKey, tunnelDefinitions) {
|
|
11
14
|
if (!this.keepAliveActive) {
|
|
12
15
|
return;
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SandboxesContainer = void 0;
|
|
4
4
|
class SandboxesContainer {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
5
|
+
sandboxes = {};
|
|
6
|
+
static instance = new SandboxesContainer();
|
|
8
7
|
static get() {
|
|
9
8
|
return this.instance.sandboxes;
|
|
10
9
|
}
|
|
@@ -13,4 +12,3 @@ class SandboxesContainer {
|
|
|
13
12
|
}
|
|
14
13
|
}
|
|
15
14
|
exports.SandboxesContainer = SandboxesContainer;
|
|
16
|
-
SandboxesContainer.instance = new SandboxesContainer();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forge/tunnel",
|
|
3
|
-
"version": "5.0.1-next.
|
|
3
|
+
"version": "5.0.1-next.5",
|
|
4
4
|
"description": "Tunnel functionality for Forge CLI",
|
|
5
5
|
"author": "Atlassian",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
"compile": "tsc -b -v"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@forge/bundler": "4.15.10-next.
|
|
15
|
-
"@forge/cli-shared": "
|
|
14
|
+
"@forge/bundler": "4.15.10-next.4",
|
|
15
|
+
"@forge/cli-shared": "4.0.0-next.3",
|
|
16
16
|
"@forge/csp": "3.2.1",
|
|
17
|
-
"@forge/runtime": "5.6.1-next.
|
|
17
|
+
"@forge/runtime": "5.6.1-next.1",
|
|
18
18
|
"express": "^4.18.3",
|
|
19
19
|
"express-intercept": "^1.1.0",
|
|
20
20
|
"http-proxy-middleware": "^2.0.6",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@atlassian/xen-test-util": "^4.2.0",
|
|
30
|
-
"@forge/manifest": "7.0
|
|
30
|
+
"@forge/manifest": "7.1.0-next.1",
|
|
31
31
|
"@types/express": "^4.17.21",
|
|
32
32
|
"@types/jest": "^29.5.12",
|
|
33
33
|
"@types/node": "14.18.63",
|