@forge/tunnel 2.1.5-next.3 → 2.2.0-next.4
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 +13 -0
- package/out/index.js +2 -2
- package/out/tunnelling/command/interactors/function-change-watcher.d.ts.map +1 -1
- package/out/tunnelling/command/interactors/function-change-watcher.js +0 -1
- package/out/tunnelling/command/interactors/multi-compiler-watcher.d.ts +11 -0
- package/out/tunnelling/command/interactors/multi-compiler-watcher.d.ts.map +1 -0
- package/out/tunnelling/command/interactors/multi-compiler-watcher.js +19 -0
- package/out/tunnelling/command/interactors/tunnel-interactor.d.ts +2 -2
- package/out/tunnelling/command/interactors/tunnel-interactor.d.ts.map +1 -1
- package/out/tunnelling/command/interactors/tunnel-interactor.js +46 -38
- package/out/tunnelling/command/start-tunnel-command.d.ts +2 -1
- package/out/tunnelling/command/start-tunnel-command.d.ts.map +1 -1
- package/out/tunnelling/command/start-tunnel-command.js +22 -19
- package/out/tunnelling/servers/custom-ui-tunnel-server.d.ts +18 -0
- package/out/tunnelling/servers/custom-ui-tunnel-server.d.ts.map +1 -0
- package/out/tunnelling/servers/custom-ui-tunnel-server.js +102 -0
- package/out/tunnelling/servers/dev-server.d.ts +21 -4
- package/out/tunnelling/servers/dev-server.d.ts.map +1 -1
- package/out/tunnelling/servers/dev-server.js +72 -2
- package/out/tunnelling/servers/index.d.ts +2 -0
- package/out/tunnelling/servers/index.d.ts.map +1 -1
- package/out/tunnelling/servers/index.js +2 -0
- package/out/tunnelling/servers/native-ui-tunnel-server.d.ts +11 -0
- package/out/tunnelling/servers/native-ui-tunnel-server.d.ts.map +1 -0
- package/out/tunnelling/servers/native-ui-tunnel-server.js +90 -0
- package/out/tunnelling/servers/resource-tunnel-server.d.ts +16 -22
- package/out/tunnelling/servers/resource-tunnel-server.d.ts.map +1 -1
- package/out/tunnelling/servers/resource-tunnel-server.js +8 -86
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @forge/tunnel
|
|
2
2
|
|
|
3
|
+
## 2.2.0-next.4
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- e37918e4: Implement support for client-side UI Kit tunneling
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [e37918e4]
|
|
12
|
+
- @forge/bundler@4.1.0-next.2
|
|
13
|
+
- @forge/cli-shared@3.4.0-next.1
|
|
14
|
+
- @forge/runtime@2.6.0-next.3
|
|
15
|
+
|
|
3
16
|
## 2.1.5-next.3
|
|
4
17
|
|
|
5
18
|
### Patch Changes
|
package/out/index.js
CHANGED
|
@@ -25,13 +25,13 @@ const graphQLClient = createGraphQLClient(authenticator);
|
|
|
25
25
|
const functionHost = new tunnelling_1.LocalFunctionHost(configFile, ui, runtime_1.snapshot, fs_1.promises);
|
|
26
26
|
const localInvocationService = new tunnelling_1.LocalInvocationService(configFile, ui, inspector);
|
|
27
27
|
const tunnelInteractor = new tunnelling_1.TunnelInteractor(ui);
|
|
28
|
-
const startTunnelCommand = new tunnelling_1.StartTunnelCommand(assertiveAppConfigReader, new tunnelling_1.LocalDevelopmentServer(localInvocationService, ui), new tunnelling_1.NgrokCreateTunnelService(ui), new tunnelling_1.RegisterTunnelServiceImpl(new tunnelling_1.TunnelGraphqlClient(graphQLClient)), functionHost, inspector, ui, configFile);
|
|
28
|
+
const startTunnelCommand = new tunnelling_1.StartTunnelCommand(assertiveAppConfigReader, new tunnelling_1.LocalDevelopmentServer(localInvocationService, ui, configFile), new tunnelling_1.NgrokCreateTunnelService(ui), new tunnelling_1.RegisterTunnelServiceImpl(new tunnelling_1.TunnelGraphqlClient(graphQLClient)), functionHost, inspector, ui, configFile);
|
|
29
29
|
const runTunnel = async () => {
|
|
30
30
|
try {
|
|
31
31
|
const tunnel = await startTunnelCommand.execute({
|
|
32
32
|
environmentKey: process.env.ENVIRONMENT_KEY || 'default'
|
|
33
33
|
});
|
|
34
|
-
const monitor = await tunnelInteractor.watchApp(tunnel
|
|
34
|
+
const monitor = await tunnelInteractor.watchApp(tunnel);
|
|
35
35
|
await tunnelInteractor.handleUserExitEvent(tunnel.stopFunction, monitor);
|
|
36
36
|
}
|
|
37
37
|
catch (e) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"function-change-watcher.d.ts","sourceRoot":"","sources":["../../../../src/tunnelling/command/interactors/function-change-watcher.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,IAAI,CAAC;AAG1C,OAAO,EAAE,UAAU,EAA8B,MAAM,EAAyB,MAAM,mBAAmB,CAAC;AAC1G,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAML,eAAe,EAChB,MAAM,gBAAgB,CAAC;AAIxB,MAAM,WAAW,qBAAqB;IACpC,aAAa,CAAC,WAAW,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACxE;AASD,eAAO,MAAM,kBAAkB,KAAK,CAAC;AACrC,eAAO,MAAM,YAAY,MAAM,CAAC;AAEhC,qBAAa,iBAAkB,YAAW,qBAAqB;IAI3D,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAN/B,OAAO,CAAC,YAAY,CAA8C;gBAG/C,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,eAAe,EACzB,YAAY,EAAE,YAAY;YAG/B,mBAAmB;IAuBpB,aAAa,CAAC,WAAW,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IA8CxD,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAI1C,OAAO,CAAC,YAAY,CAElB;YAEY,8BAA8B;YAgB9B,mBAAmB;
|
|
1
|
+
{"version":3,"file":"function-change-watcher.d.ts","sourceRoot":"","sources":["../../../../src/tunnelling/command/interactors/function-change-watcher.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,IAAI,CAAC;AAG1C,OAAO,EAAE,UAAU,EAA8B,MAAM,EAAyB,MAAM,mBAAmB,CAAC;AAC1G,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAML,eAAe,EAChB,MAAM,gBAAgB,CAAC;AAIxB,MAAM,WAAW,qBAAqB;IACpC,aAAa,CAAC,WAAW,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACxE;AASD,eAAO,MAAM,kBAAkB,KAAK,CAAC;AACrC,eAAO,MAAM,YAAY,MAAM,CAAC;AAEhC,qBAAa,iBAAkB,YAAW,qBAAqB;IAI3D,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAN/B,OAAO,CAAC,YAAY,CAA8C;gBAG/C,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,eAAe,EACzB,YAAY,EAAE,YAAY;YAG/B,mBAAmB;IAuBpB,aAAa,CAAC,WAAW,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IA8CxD,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAI1C,OAAO,CAAC,YAAY,CAElB;YAEY,8BAA8B;YAgB9B,mBAAmB;CAoBlC"}
|
|
@@ -104,7 +104,6 @@ class LocalFunctionHost {
|
|
|
104
104
|
});
|
|
105
105
|
const resolveds = await Promise.all(promises);
|
|
106
106
|
util_1.SandboxesContainer.updateSandboxes(resolveds.reduce((acc, obj) => Object.assign(acc, obj), {}));
|
|
107
|
-
this.logger.info(cli_shared_1.LogColor.trace(cli_shared_1.Text.tunnel.reloaded));
|
|
108
107
|
}
|
|
109
108
|
catch (error) {
|
|
110
109
|
this.logger.error(error);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { BundlerOutput, WatcherMonitor } from '@forge/bundler';
|
|
2
|
+
import { DevelopmentServer, WatchHooks } from '../../servers';
|
|
3
|
+
export declare class MultiCompilerWatcher implements WatcherMonitor {
|
|
4
|
+
private readonly servers;
|
|
5
|
+
constructor(servers: DevelopmentServer[]);
|
|
6
|
+
compileAndWatch({ onChange: { onBuildWillStart, onBuildFinished } }: {
|
|
7
|
+
onChange: WatchHooks;
|
|
8
|
+
}): Promise<BundlerOutput>;
|
|
9
|
+
stop(): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=multi-compiler-watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-compiler-watcher.d.ts","sourceRoot":"","sources":["../../../../src/tunnelling/command/interactors/multi-compiler-watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE9D,qBAAa,oBAAqB,YAAW,cAAc;IAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,iBAAiB,EAAE;IAE5C,eAAe,CAAC,EAC3B,QAAQ,EAAE,EAAE,gBAAgB,EAAE,eAAe,EAAE,EAChD,EAAE;QACD,QAAQ,EAAE,UAAU,CAAC;KACtB,GAAG,OAAO,CAAC,aAAa,CAAC;IAab,IAAI;CAGlB"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MultiCompilerWatcher = void 0;
|
|
4
|
+
class MultiCompilerWatcher {
|
|
5
|
+
constructor(servers) {
|
|
6
|
+
this.servers = servers;
|
|
7
|
+
}
|
|
8
|
+
async compileAndWatch({ onChange: { onBuildWillStart, onBuildFinished } }) {
|
|
9
|
+
const results = await Promise.all(this.servers.map((server) => server.compileAndWatch({
|
|
10
|
+
onBuildWillStart,
|
|
11
|
+
onBuildFinished
|
|
12
|
+
})));
|
|
13
|
+
return results.reduce((prev, curr) => (Object.assign(Object.assign({}, prev), curr)), {});
|
|
14
|
+
}
|
|
15
|
+
async stop() {
|
|
16
|
+
await Promise.all(this.servers.map((server) => server.stop()));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.MultiCompilerWatcher = MultiCompilerWatcher;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { WatcherMonitor } from '@forge/bundler';
|
|
2
|
-
import {
|
|
2
|
+
import { Logger } from '@forge/cli-shared';
|
|
3
3
|
import { StartTunnelResult } from '../start-tunnel-command';
|
|
4
4
|
export declare class TunnelInteractor {
|
|
5
5
|
private readonly logger;
|
|
6
6
|
constructor(logger: Logger);
|
|
7
7
|
handleUserExitEvent(stopFunction: () => Promise<void>, bundleMonitor: WatcherMonitor | undefined): Promise<void>;
|
|
8
|
-
watchApp: (startTunnelResult: StartTunnelResult
|
|
8
|
+
watchApp: (startTunnelResult: StartTunnelResult) => Promise<WatcherMonitor | undefined>;
|
|
9
9
|
}
|
|
10
10
|
//# sourceMappingURL=tunnel-interactor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tunnel-interactor.d.ts","sourceRoot":"","sources":["../../../../src/tunnelling/command/interactors/tunnel-interactor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tunnel-interactor.d.ts","sourceRoot":"","sources":["../../../../src/tunnelling/command/interactors/tunnel-interactor.ts"],"names":[],"mappings":"AACA,OAAO,EAA4B,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC1E,OAAO,EAAY,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAG5D,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM;IAEpC,mBAAmB,CACxB,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EACjC,aAAa,EAAE,cAAc,GAAG,SAAS,GACxC,OAAO,CAAC,IAAI,CAAC;IAqCT,QAAQ,sBAA6B,iBAAiB,KAAG,QAAQ,cAAc,GAAG,SAAS,CAAC,CA6DjG;CACH"}
|
|
@@ -2,51 +2,58 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TunnelInteractor = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const path_1 = tslib_1.__importDefault(require("path"));
|
|
6
5
|
const readline_1 = tslib_1.__importDefault(require("readline"));
|
|
7
|
-
const cli_shared_1 = require("@forge/cli-shared");
|
|
8
6
|
const bundler_1 = require("@forge/bundler");
|
|
9
|
-
const
|
|
7
|
+
const cli_shared_1 = require("@forge/cli-shared");
|
|
8
|
+
const multi_compiler_watcher_1 = require("./multi-compiler-watcher");
|
|
10
9
|
class TunnelInteractor {
|
|
11
10
|
constructor(logger) {
|
|
12
11
|
this.logger = logger;
|
|
13
|
-
this.watchApp = async (startTunnelResult
|
|
14
|
-
const { localPort, inspectorAddress, reloadSandboxes } = startTunnelResult;
|
|
12
|
+
this.watchApp = async (startTunnelResult) => {
|
|
13
|
+
const { localPort, inspectorAddress, reloadSandboxes, devServers } = startTunnelResult;
|
|
15
14
|
if (inspectorAddress) {
|
|
16
15
|
this.logger.info(cli_shared_1.Text.tunnel.startedInspector(inspectorAddress));
|
|
17
16
|
}
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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);
|
|
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);
|
|
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;
|
|
50
57
|
}
|
|
51
58
|
};
|
|
52
59
|
}
|
|
@@ -70,9 +77,10 @@ class TunnelInteractor {
|
|
|
70
77
|
}
|
|
71
78
|
finally {
|
|
72
79
|
if (bundleMonitor) {
|
|
73
|
-
bundleMonitor.stop();
|
|
80
|
+
await bundleMonitor.stop();
|
|
74
81
|
}
|
|
75
82
|
this.logger.info(cli_shared_1.LogColor.trace(cli_shared_1.Text.tunnel.stoppedTunnel));
|
|
83
|
+
process.exit();
|
|
76
84
|
}
|
|
77
85
|
};
|
|
78
86
|
rl.on('SIGINT', tunnelCleanupListener);
|
|
@@ -13,6 +13,7 @@ export interface StartTunnelResult {
|
|
|
13
13
|
localPort: number;
|
|
14
14
|
tunnelDefinitions: TunnelDefinitions;
|
|
15
15
|
inspectorAddress?: string;
|
|
16
|
+
devServers: DevelopmentServer[];
|
|
16
17
|
stopFunction(): Promise<void>;
|
|
17
18
|
reloadSandboxes(bundledCode: BundlerOutput): Promise<void>;
|
|
18
19
|
}
|
|
@@ -30,7 +31,7 @@ export declare class StartTunnelCommand {
|
|
|
30
31
|
constructor(getAppConfig: AppConfigProvider, devServer: DevelopmentServer, tunnelFactory: CreateTunnelService, tunnelClient: RegisterTunnelService, functionHost: FunctionChangeWatcher, inspector: Inspector, logger: Logger, configFile: ConfigFile);
|
|
31
32
|
private stopServices;
|
|
32
33
|
private startFaaSTunnelServer;
|
|
33
|
-
private
|
|
34
|
+
private startResourceBasedTunnelsServers;
|
|
34
35
|
execute(options: StartTunnelOptions): Promise<StartTunnelResult>;
|
|
35
36
|
}
|
|
36
37
|
//# sourceMappingURL=start-tunnel-command.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start-tunnel-command.d.ts","sourceRoot":"","sources":["../../../src/tunnelling/command/start-tunnel-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"start-tunnel-command.d.ts","sourceRoot":"","sources":["../../../src/tunnelling/command/start-tunnel-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,EAAyB,MAAM,mBAAmB,CAAC;AACjG,OAAO,EAAE,SAAS,EAAqB,MAAM,gBAAgB,CAAC;AAG9D,OAAO,EACL,iBAAiB,EAKlB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAsC,iBAAiB,EAAE,MAAM,UAAU,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACzE,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,iBAAiB,CAAC;IACrC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,eAAe,CAAC,WAAW,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5D;AAED,qBAAa,kBAAkB;IAK3B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAX7B,OAAO,CAAC,aAAa,CAAmE;IACxF,OAAO,CAAC,iBAAiB,CAAgC;gBAGtC,YAAY,EAAE,iBAAiB,EAC/B,SAAS,EAAE,iBAAiB,EAC5B,aAAa,EAAE,mBAAmB,EAClC,YAAY,EAAE,qBAAqB,EACnC,YAAY,EAAE,qBAAqB,EACnC,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU;IAGzC,OAAO,CAAC,YAAY,CAUlB;IAEF,OAAO,CAAC,qBAAqB,CAS3B;IAEF,OAAO,CAAC,gCAAgC,CAgCtC;IAEW,OAAO,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAoD9E"}
|
|
@@ -4,7 +4,6 @@ exports.StartTunnelCommand = void 0;
|
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const cli_shared_1 = require("@forge/cli-shared");
|
|
6
6
|
const runtime_1 = require("@forge/runtime");
|
|
7
|
-
const url_1 = require("url");
|
|
8
7
|
const node_cache_1 = tslib_1.__importDefault(require("node-cache"));
|
|
9
8
|
const servers_1 = require("../servers");
|
|
10
9
|
const index_1 = require("../index");
|
|
@@ -33,17 +32,13 @@ class StartTunnelCommand {
|
|
|
33
32
|
};
|
|
34
33
|
this.startFaaSTunnelServer = async (port) => {
|
|
35
34
|
const { permissions = {}, remotes = [] } = await this.configFile.readConfig();
|
|
36
|
-
const
|
|
37
|
-
const faasTunnelUrl = await this.tunnelFactory.establishTunnel(
|
|
38
|
-
return {
|
|
39
|
-
port: localPort,
|
|
40
|
-
tunnelUrl: faasTunnelUrl
|
|
41
|
-
};
|
|
35
|
+
const serverInfo = await this.devServer.start(port, permissions, remotes);
|
|
36
|
+
const faasTunnelUrl = await this.tunnelFactory.establishTunnel(serverInfo.port);
|
|
37
|
+
return Object.assign(Object.assign({}, serverInfo), { tunnelUrl: faasTunnelUrl });
|
|
42
38
|
};
|
|
43
|
-
this.
|
|
39
|
+
this.startResourceBasedTunnelsServers = async (resourceDetails) => {
|
|
44
40
|
var _a, _b;
|
|
45
41
|
const resourcePortMap = JSON.parse((_a = process.env.RESOURCE_PORT_MAP) !== null && _a !== void 0 ? _a : '{}');
|
|
46
|
-
const resourceDetails = await this.configFile.getResources();
|
|
47
42
|
const { permissions = {}, remotes = [] } = await this.configFile.readConfig();
|
|
48
43
|
const cspReporterPort = parseInt((_b = process.env.CSP_REPORTER_PORT) !== null && _b !== void 0 ? _b : '4000', 10);
|
|
49
44
|
if (resourceDetails.length === 0)
|
|
@@ -51,27 +46,28 @@ class StartTunnelCommand {
|
|
|
51
46
|
this.cspReporterServer = new servers_1.CspReporterServer(cspReporterPort, this.logger, new node_cache_1.default());
|
|
52
47
|
await this.cspReporterServer.start();
|
|
53
48
|
return await Promise.all(resourceDetails.map(async (rd) => {
|
|
54
|
-
const { key } = rd;
|
|
49
|
+
const { key, resourceType } = rd;
|
|
55
50
|
const port = resourcePortMap[key];
|
|
56
|
-
|
|
51
|
+
const tunnelServer = resourceType === 'nativeUI' ? servers_1.NativeUITunnelServer : servers_1.CustomUITunnelServer;
|
|
52
|
+
this.tunnelServers[key] = new tunnelServer(Object.assign(Object.assign({}, rd), { port, logger: this.logger, cspReporterServerPort: cspReporterPort, permissions,
|
|
57
53
|
remotes }));
|
|
58
|
-
|
|
59
|
-
return {
|
|
60
|
-
resourceKey: key,
|
|
61
|
-
tunnelUrl: new url_1.URL(`http://localhost:${port}`)
|
|
62
|
-
};
|
|
54
|
+
return this.tunnelServers[key].start();
|
|
63
55
|
}));
|
|
64
56
|
};
|
|
65
57
|
}
|
|
66
58
|
async execute(options) {
|
|
67
59
|
const { id: appId } = await this.getAppConfig();
|
|
68
60
|
const { port, environmentKey } = options;
|
|
61
|
+
const allResources = await this.configFile.getResources();
|
|
69
62
|
try {
|
|
70
63
|
const faasTunnelServer = await this.startFaaSTunnelServer(port);
|
|
71
|
-
const customUITunnelsServers = await this.
|
|
64
|
+
const customUITunnelsServers = await this.startResourceBasedTunnelsServers(allResources);
|
|
72
65
|
const tunnelDefinitions = {
|
|
73
66
|
faasTunnelUrl: faasTunnelServer.tunnelUrl,
|
|
74
|
-
customUI: customUITunnelsServers
|
|
67
|
+
customUI: customUITunnelsServers.map(({ tunnelUrl, resourceKey }) => ({
|
|
68
|
+
tunnelUrl,
|
|
69
|
+
resourceKey
|
|
70
|
+
}))
|
|
75
71
|
};
|
|
76
72
|
await this.tunnelClient.registerTunnels(appId, environmentKey, tunnelDefinitions);
|
|
77
73
|
const inspectorAddress = (0, index_1.isInspectorEnabled)() ? this.inspector.startServer(index_1.INSPECTOR_PORT) : undefined;
|
|
@@ -90,7 +86,14 @@ class StartTunnelCommand {
|
|
|
90
86
|
}
|
|
91
87
|
}
|
|
92
88
|
};
|
|
93
|
-
return {
|
|
89
|
+
return {
|
|
90
|
+
localPort: faasTunnelServer.port,
|
|
91
|
+
tunnelDefinitions,
|
|
92
|
+
inspectorAddress,
|
|
93
|
+
stopFunction,
|
|
94
|
+
reloadSandboxes,
|
|
95
|
+
devServers: [faasTunnelServer.devServer, ...customUITunnelsServers.map(({ devServer }) => devServer)]
|
|
96
|
+
};
|
|
94
97
|
}
|
|
95
98
|
catch (e) {
|
|
96
99
|
try {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Express } from 'express';
|
|
2
|
+
import { ResourceTunnelServer, ResourceTunnelServerArgs } from './resource-tunnel-server';
|
|
3
|
+
import { DevelopmentServer, StartDevServerResult } from './dev-server';
|
|
4
|
+
export declare class CustomUITunnelServer extends ResourceTunnelServer implements DevelopmentServer {
|
|
5
|
+
private readonly tunnelArgs;
|
|
6
|
+
private readonly app;
|
|
7
|
+
private server;
|
|
8
|
+
private readonly proxy;
|
|
9
|
+
private socket;
|
|
10
|
+
constructor(tunnelArgs: ResourceTunnelServerArgs);
|
|
11
|
+
start(): Promise<Required<StartDevServerResult>>;
|
|
12
|
+
stop(): Promise<void>;
|
|
13
|
+
compileAndWatch(): Promise<any>;
|
|
14
|
+
getApp(): Express;
|
|
15
|
+
private handleProxyDestinationNotStarted;
|
|
16
|
+
private handleWebsocketUpgrade;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=custom-ui-tunnel-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"custom-ui-tunnel-server.d.ts","sourceRoot":"","sources":["../../../src/tunnelling/servers/custom-ui-tunnel-server.ts"],"names":[],"mappings":"AAEA,OAAgB,EAAE,OAAO,EAAqB,MAAM,SAAS,CAAC;AAG9D,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAoB,MAAM,0BAA0B,CAAC;AAE5G,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AASvE,qBAAa,oBAAqB,SAAQ,oBAAqB,YAAW,iBAAiB;IAM7E,OAAO,CAAC,QAAQ,CAAC,UAAU;IALvC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAU;IAC9B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IACnD,OAAO,CAAC,MAAM,CAAqB;gBAEN,UAAU,EAAE,wBAAwB;IAwC3D,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC;IAkBhD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAcd,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC;IAK5C,MAAM,IAAI,OAAO;IAIjB,OAAO,CAAC,gCAAgC;IAoBxC,OAAO,CAAC,sBAAsB;CAO/B"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CustomUITunnelServer = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const url_1 = require("url");
|
|
6
|
+
const express_1 = tslib_1.__importDefault(require("express"));
|
|
7
|
+
const http_proxy_middleware_1 = require("http-proxy-middleware");
|
|
8
|
+
const resource_tunnel_server_1 = require("./resource-tunnel-server");
|
|
9
|
+
const cli_shared_1 = require("@forge/cli-shared");
|
|
10
|
+
var ConnectionErrorCode;
|
|
11
|
+
(function (ConnectionErrorCode) {
|
|
12
|
+
ConnectionErrorCode["REFUSED"] = "ECONNREFUSED";
|
|
13
|
+
})(ConnectionErrorCode || (ConnectionErrorCode = {}));
|
|
14
|
+
class CustomUITunnelServer extends resource_tunnel_server_1.ResourceTunnelServer {
|
|
15
|
+
constructor(tunnelArgs) {
|
|
16
|
+
super(tunnelArgs);
|
|
17
|
+
this.tunnelArgs = tunnelArgs;
|
|
18
|
+
const { tunnel, permissions, remotes } = tunnelArgs;
|
|
19
|
+
this.app = (0, express_1.default)();
|
|
20
|
+
this.app.use(this.getCustomUIHtmlTransformMiddleware(permissions, remotes));
|
|
21
|
+
if (tunnel) {
|
|
22
|
+
const { port: tunnelPort } = tunnel;
|
|
23
|
+
this.proxy = (0, http_proxy_middleware_1.createProxyMiddleware)({
|
|
24
|
+
target: `http://${resource_tunnel_server_1.TUNNEL_LOCALHOST}:${tunnelPort}`,
|
|
25
|
+
ws: true,
|
|
26
|
+
logLevel: 'info',
|
|
27
|
+
logProvider: () => {
|
|
28
|
+
return {
|
|
29
|
+
log: this.logger.trace,
|
|
30
|
+
debug: this.logger.trace,
|
|
31
|
+
info: this.logger.trace,
|
|
32
|
+
warn: this.logger.warn,
|
|
33
|
+
error: this.logger.error
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
onError: (err, req, res) => {
|
|
37
|
+
this.handleProxyDestinationNotStarted(err, req.url, res, tunnelPort);
|
|
38
|
+
},
|
|
39
|
+
onProxyReq: (_proxyReq, req) => {
|
|
40
|
+
this.logFileServed(req.url, (input) => cli_shared_1.Text.tunnel.customUI.fileProxied(input, this.key, tunnelPort));
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
this.app.use('/', this.proxy);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
this.app.use((req, _res, next) => {
|
|
47
|
+
this.logFileServed(req.url, (input) => cli_shared_1.Text.tunnel.customUI.fileServed(input, this.key));
|
|
48
|
+
next();
|
|
49
|
+
});
|
|
50
|
+
this.app.use(express_1.default.static(this.path));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async start() {
|
|
54
|
+
return new Promise((resolve) => {
|
|
55
|
+
const { key, port } = this.tunnelArgs;
|
|
56
|
+
const result = {
|
|
57
|
+
port,
|
|
58
|
+
devServer: this,
|
|
59
|
+
resourceKey: key,
|
|
60
|
+
tunnelUrl: new url_1.URL(`http://localhost:${port}`)
|
|
61
|
+
};
|
|
62
|
+
this.server = this.app.listen(this.port, () => resolve(result));
|
|
63
|
+
this.server.on('upgrade', (req, socket, head) => this.handleWebsocketUpgrade(req, socket, head));
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
async stop() {
|
|
67
|
+
if (this.socket) {
|
|
68
|
+
this.socket.end();
|
|
69
|
+
}
|
|
70
|
+
return new Promise((resolve, reject) => {
|
|
71
|
+
if (!this.server) {
|
|
72
|
+
return resolve();
|
|
73
|
+
}
|
|
74
|
+
this.server.close((err) => (err ? reject(err) : resolve()));
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
async compileAndWatch() {
|
|
78
|
+
return {};
|
|
79
|
+
}
|
|
80
|
+
getApp() {
|
|
81
|
+
return this.app;
|
|
82
|
+
}
|
|
83
|
+
handleProxyDestinationNotStarted(err, reqUrl, res, tunnelPort) {
|
|
84
|
+
if ((err === null || err === void 0 ? void 0 : err.code) !== ConnectionErrorCode.REFUSED || (reqUrl !== '/' && reqUrl !== 'index.html')) {
|
|
85
|
+
this.logger.error(err);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
res.writeHead(500, {
|
|
89
|
+
'Content-Type': 'text/plain'
|
|
90
|
+
});
|
|
91
|
+
this.logger.error(new Error(cli_shared_1.Text.tunnel.error.serverNotStartedOnPort(tunnelPort)));
|
|
92
|
+
res.end(cli_shared_1.Text.tunnel.error.serverNotStartedOnPort(tunnelPort));
|
|
93
|
+
}
|
|
94
|
+
handleWebsocketUpgrade(req, socket, head) {
|
|
95
|
+
var _a;
|
|
96
|
+
this.socket = socket;
|
|
97
|
+
if ((_a = this.proxy) === null || _a === void 0 ? void 0 : _a.upgrade) {
|
|
98
|
+
return this.proxy.upgrade(req, socket, head);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exports.CustomUITunnelServer = CustomUITunnelServer;
|
|
@@ -1,10 +1,23 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import express from 'express';
|
|
2
|
-
import {
|
|
3
|
+
import { URL } from 'url';
|
|
4
|
+
import { ConfigFile, Logger } from '@forge/cli-shared';
|
|
3
5
|
import { ExternalRequestBody } from '@forge/runtime';
|
|
4
6
|
import { Permissions, Remotes } from '@forge/manifest';
|
|
7
|
+
export interface WatchHooks<T = any> {
|
|
8
|
+
onBuildWillStart: () => Promise<void>;
|
|
9
|
+
onBuildFinished: (err: Error | null, result?: T) => Promise<void>;
|
|
10
|
+
}
|
|
5
11
|
export interface DevelopmentServer {
|
|
6
|
-
start(port?: number, permissions?: Permissions, remotes?: Remotes): Promise<
|
|
12
|
+
start(port?: number, permissions?: Permissions, remotes?: Remotes): Promise<StartDevServerResult>;
|
|
7
13
|
stop(): Promise<void>;
|
|
14
|
+
compileAndWatch<T = any>(hooks: WatchHooks<T>): Promise<any>;
|
|
15
|
+
}
|
|
16
|
+
export interface StartDevServerResult {
|
|
17
|
+
port: number;
|
|
18
|
+
devServer: DevelopmentServer;
|
|
19
|
+
resourceKey?: string;
|
|
20
|
+
tunnelUrl?: URL;
|
|
8
21
|
}
|
|
9
22
|
export interface InvocationService {
|
|
10
23
|
invoke(handler: string, request: ExternalRequestBody): Promise<any>;
|
|
@@ -12,14 +25,18 @@ export interface InvocationService {
|
|
|
12
25
|
export declare class LocalDevelopmentServer implements DevelopmentServer {
|
|
13
26
|
private readonly invocationService;
|
|
14
27
|
private readonly logger;
|
|
28
|
+
private readonly configFile;
|
|
15
29
|
private app;
|
|
16
30
|
private httpServer;
|
|
17
31
|
private permissions;
|
|
18
32
|
private remotes;
|
|
19
|
-
constructor(invocationService: InvocationService, logger: Logger);
|
|
20
|
-
start(port?: number, permissions?: Permissions, remotes?: Remotes): Promise<
|
|
33
|
+
constructor(invocationService: InvocationService, logger: Logger, configFile: ConfigFile);
|
|
34
|
+
start(port?: number, permissions?: Permissions, remotes?: Remotes): Promise<StartDevServerResult>;
|
|
21
35
|
stop(): Promise<void>;
|
|
36
|
+
compileAndWatch<BundlerOutput>({ onBuildWillStart, onBuildFinished }: WatchHooks<BundlerOutput>): Promise<BundlerOutput | undefined>;
|
|
22
37
|
getApp(): express.Application;
|
|
23
38
|
handleInvocation: express.Handler;
|
|
39
|
+
private getEntryPoints;
|
|
40
|
+
private getRuntimeCompiler;
|
|
24
41
|
}
|
|
25
42
|
//# sourceMappingURL=dev-server.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../../../src/tunnelling/servers/dev-server.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAI9B,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../../../src/tunnelling/servers/dev-server.ts"],"names":[],"mappings":";AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAI9B,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAG1B,OAAO,EAAE,UAAU,EAAY,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAe,MAAM,gBAAgB,CAAC;AAGlE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAQvD,MAAM,WAAW,UAAU,CAAC,CAAC,GAAG,GAAG;IACjC,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,eAAe,EAAE,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACnE;AACD,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAClG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,eAAe,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;CAC9D;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,iBAAiB,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,GAAG,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;CACrE;AAED,qBAAa,sBAAuB,YAAW,iBAAiB;IAO5D,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAR7B,OAAO,CAAC,GAAG,CAAsB;IACjC,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,WAAW,CAA0B;IAC7C,OAAO,CAAC,OAAO,CAAsB;gBAGlB,iBAAiB,EAAE,iBAAiB,EACpC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,UAAU;IAQ5B,KAAK,CAAC,IAAI,SAAI,EAAE,WAAW,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,oBAAoB,CAAC;IAe5F,IAAI;IAUJ,eAAe,CAAC,aAAa,EAAE,EAC1C,gBAAgB,EAChB,eAAe,EAChB,EAAE,UAAU,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;IAwC1D,MAAM,IAAI,OAAO,CAAC,WAAW;IAI7B,gBAAgB,EAAE,OAAO,CAAC,OAAO,CAsCtC;IAEF,OAAO,CAAC,cAAc,CAepB;IAEF,OAAO,CAAC,kBAAkB,CAsBxB;CACH"}
|
|
@@ -3,12 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.LocalDevelopmentServer = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const express_1 = tslib_1.__importDefault(require("express"));
|
|
6
|
+
const path_1 = tslib_1.__importDefault(require("path"));
|
|
7
|
+
const cli_shared_1 = require("@forge/cli-shared");
|
|
6
8
|
const runtime_1 = require("@forge/runtime");
|
|
9
|
+
const __1 = require("../");
|
|
7
10
|
const util_1 = require("../util");
|
|
11
|
+
const bundler_1 = require("@forge/bundler");
|
|
8
12
|
class LocalDevelopmentServer {
|
|
9
|
-
constructor(invocationService, logger) {
|
|
13
|
+
constructor(invocationService, logger, configFile) {
|
|
10
14
|
this.invocationService = invocationService;
|
|
11
15
|
this.logger = logger;
|
|
16
|
+
this.configFile = configFile;
|
|
12
17
|
this.handleInvocation = async (req, res) => {
|
|
13
18
|
var _a, _b, _c, _d, _e, _f;
|
|
14
19
|
const request = req.body;
|
|
@@ -39,6 +44,36 @@ class LocalDevelopmentServer {
|
|
|
39
44
|
}
|
|
40
45
|
}
|
|
41
46
|
};
|
|
47
|
+
this.getEntryPoints = async () => {
|
|
48
|
+
const handlers = await this.configFile.getAppHandlers();
|
|
49
|
+
const currentDirectory = process.cwd();
|
|
50
|
+
const entryPoints = [];
|
|
51
|
+
for (const handler of handlers) {
|
|
52
|
+
entryPoints.push({
|
|
53
|
+
name: handler,
|
|
54
|
+
path: path_1.default.join(currentDirectory, 'src', handler)
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return entryPoints;
|
|
58
|
+
};
|
|
59
|
+
this.getRuntimeCompiler = async () => {
|
|
60
|
+
const entryPoints = await this.getEntryPoints();
|
|
61
|
+
if (!entryPoints.length) {
|
|
62
|
+
return {
|
|
63
|
+
compiler: undefined,
|
|
64
|
+
entryPoints
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
const config = (0, bundler_1.getSandboxedRuntimeBuildConfig)(entryPoints, {
|
|
68
|
+
isWatchMode: true,
|
|
69
|
+
isDebugMode: (0, __1.isInspectorEnabled)(),
|
|
70
|
+
appDirectory: process.cwd()
|
|
71
|
+
});
|
|
72
|
+
return {
|
|
73
|
+
compiler: (0, bundler_1.getCompiler)(config),
|
|
74
|
+
entryPoints
|
|
75
|
+
};
|
|
76
|
+
};
|
|
42
77
|
this.app = (0, express_1.default)();
|
|
43
78
|
this.app.use(express_1.default.json({ limit: '6mb' }));
|
|
44
79
|
this.app.post(`/:fnKey`, this.handleInvocation);
|
|
@@ -50,7 +85,10 @@ class LocalDevelopmentServer {
|
|
|
50
85
|
const httpServer = this.app.listen({ port });
|
|
51
86
|
httpServer.on('error', reject).on('listening', () => resolve(httpServer));
|
|
52
87
|
});
|
|
53
|
-
return
|
|
88
|
+
return {
|
|
89
|
+
port: this.httpServer.address().port,
|
|
90
|
+
devServer: this
|
|
91
|
+
};
|
|
54
92
|
}
|
|
55
93
|
async stop() {
|
|
56
94
|
if (!this.httpServer) {
|
|
@@ -60,6 +98,38 @@ class LocalDevelopmentServer {
|
|
|
60
98
|
this.httpServer = undefined;
|
|
61
99
|
await new Promise((resolve, reject) => server.close((err) => (err ? reject(err) : resolve())));
|
|
62
100
|
}
|
|
101
|
+
async compileAndWatch({ onBuildWillStart, onBuildFinished }) {
|
|
102
|
+
const { compiler, entryPoints } = await this.getRuntimeCompiler();
|
|
103
|
+
if (!compiler) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
let isFirstRun = true;
|
|
107
|
+
compiler.hooks.watchRun.tapAsync('watchRun', async (_, watchRunCallback) => {
|
|
108
|
+
if (!isFirstRun) {
|
|
109
|
+
await onBuildWillStart();
|
|
110
|
+
}
|
|
111
|
+
watchRunCallback();
|
|
112
|
+
});
|
|
113
|
+
return new Promise((resolve, reject) => {
|
|
114
|
+
compiler.watch({ poll: 1000 }, async (compilerError, stats) => {
|
|
115
|
+
try {
|
|
116
|
+
(0, bundler_1.handleWebpackCompilationResult)(compilerError, stats);
|
|
117
|
+
this.logger.info(cli_shared_1.LogColor.trace(cli_shared_1.Text.tunnel.functionsBundlingSucceeded));
|
|
118
|
+
const bundle = (0, bundler_1.getInMemoryBundle)(entryPoints);
|
|
119
|
+
if (!isFirstRun) {
|
|
120
|
+
await onBuildFinished(null, bundle);
|
|
121
|
+
}
|
|
122
|
+
isFirstRun = false;
|
|
123
|
+
resolve(bundle);
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
await onBuildFinished(err);
|
|
127
|
+
isFirstRun = false;
|
|
128
|
+
reject(err);
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
}
|
|
63
133
|
getApp() {
|
|
64
134
|
return this.app;
|
|
65
135
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tunnelling/servers/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/tunnelling/servers/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,uBAAuB,CAAC"}
|
|
@@ -3,4 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
tslib_1.__exportStar(require("./dev-server"), exports);
|
|
5
5
|
tslib_1.__exportStar(require("./resource-tunnel-server"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./custom-ui-tunnel-server"), exports);
|
|
7
|
+
tslib_1.__exportStar(require("./native-ui-tunnel-server"), exports);
|
|
6
8
|
tslib_1.__exportStar(require("./csp-reporter-server"), exports);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ResourceTunnelServer, ResourceTunnelServerArgs } from './resource-tunnel-server';
|
|
2
|
+
import { DevelopmentServer, StartDevServerResult, WatchHooks } from './dev-server';
|
|
3
|
+
export declare class NativeUITunnelServer extends ResourceTunnelServer implements DevelopmentServer {
|
|
4
|
+
private readonly tunnelArgs;
|
|
5
|
+
private readonly server;
|
|
6
|
+
constructor(tunnelArgs: ResourceTunnelServerArgs);
|
|
7
|
+
start(): Promise<Required<StartDevServerResult>>;
|
|
8
|
+
compileAndWatch({ onBuildWillStart, onBuildFinished }: WatchHooks): Promise<void>;
|
|
9
|
+
stop(): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=native-ui-tunnel-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-ui-tunnel-server.d.ts","sourceRoot":"","sources":["../../../src/tunnelling/servers/native-ui-tunnel-server.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAoB,MAAM,0BAA0B,CAAC;AAG5G,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAEnF,qBAAa,oBAAqB,SAAQ,oBAAqB,YAAW,iBAAiB;IAG7E,OAAO,CAAC,QAAQ,CAAC,UAAU;IAFvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;gBAEb,UAAU,EAAE,wBAAwB;IAoD3D,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAC;IAWzC,eAAe,CAAC,EAAE,gBAAgB,EAAE,eAAe,EAAE,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAsCxF,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAG5B"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NativeUITunnelServer = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const webpack_dev_server_1 = tslib_1.__importDefault(require("webpack-dev-server"));
|
|
6
|
+
const bundler_1 = require("@forge/bundler");
|
|
7
|
+
const resource_tunnel_server_1 = require("./resource-tunnel-server");
|
|
8
|
+
const cli_shared_1 = require("@forge/cli-shared");
|
|
9
|
+
const url_1 = require("url");
|
|
10
|
+
class NativeUITunnelServer extends resource_tunnel_server_1.ResourceTunnelServer {
|
|
11
|
+
constructor(tunnelArgs) {
|
|
12
|
+
super(tunnelArgs);
|
|
13
|
+
this.tunnelArgs = tunnelArgs;
|
|
14
|
+
const { key, path, port, permissions, remotes } = tunnelArgs;
|
|
15
|
+
const entrypoint = { name: key, path };
|
|
16
|
+
const config = (0, bundler_1.getNativeUiBuildConfig)([entrypoint]);
|
|
17
|
+
const compiler = (0, bundler_1.getCompiler)(Object.assign(Object.assign({}, config), { infrastructureLogging: {
|
|
18
|
+
level: 'error'
|
|
19
|
+
}, stats: 'errors-only', watchOptions: {
|
|
20
|
+
aggregateTimeout: 200,
|
|
21
|
+
poll: 1000,
|
|
22
|
+
ignored: '**/node_modules'
|
|
23
|
+
} }));
|
|
24
|
+
this.server = new webpack_dev_server_1.default({
|
|
25
|
+
port,
|
|
26
|
+
host: resource_tunnel_server_1.TUNNEL_LOCALHOST,
|
|
27
|
+
setupMiddlewares: (middlewares) => {
|
|
28
|
+
const index = middlewares.findIndex((middleware) => middleware.name === 'webpack-dev-middleware');
|
|
29
|
+
middlewares.splice(index, 0, {
|
|
30
|
+
name: 'custom-ui-scripts-middleware',
|
|
31
|
+
middleware: this.getCustomUIHtmlTransformMiddleware(permissions, remotes)
|
|
32
|
+
});
|
|
33
|
+
middlewares.unshift({
|
|
34
|
+
name: 'logging-middleware',
|
|
35
|
+
middleware: (req, _, next) => {
|
|
36
|
+
this.logFileServed(req.url, (input) => cli_shared_1.Text.tunnel.customUI.fileServed(input, this.key));
|
|
37
|
+
next();
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
return middlewares;
|
|
41
|
+
}
|
|
42
|
+
}, compiler);
|
|
43
|
+
}
|
|
44
|
+
async start() {
|
|
45
|
+
const { key, port } = this.tunnelArgs;
|
|
46
|
+
return {
|
|
47
|
+
port,
|
|
48
|
+
devServer: this,
|
|
49
|
+
resourceKey: key,
|
|
50
|
+
tunnelUrl: new url_1.URL(`http://${resource_tunnel_server_1.TUNNEL_LOCALHOST}:${port}`)
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
async compileAndWatch({ onBuildWillStart, onBuildFinished }) {
|
|
54
|
+
await this.server.start();
|
|
55
|
+
const compiler = this.server.compiler;
|
|
56
|
+
compiler.hooks.watchRun.tapAsync('watchRun', async (_, watchRunCallback) => {
|
|
57
|
+
await onBuildWillStart();
|
|
58
|
+
watchRunCallback();
|
|
59
|
+
});
|
|
60
|
+
let isFirtCompilation = true;
|
|
61
|
+
return new Promise((resolve, reject) => {
|
|
62
|
+
compiler.hooks.done.tapAsync('done', async (stats, doneCallback) => {
|
|
63
|
+
const maybeError = stats.hasErrors() ? stats.compilation.getErrors()[0] : undefined;
|
|
64
|
+
try {
|
|
65
|
+
(0, bundler_1.handleWebpackCompilationResult)(maybeError, stats);
|
|
66
|
+
this.logger.info(cli_shared_1.LogColor.trace(cli_shared_1.Text.tunnel.resourcesBundlingSucceeded));
|
|
67
|
+
if (!isFirtCompilation) {
|
|
68
|
+
await onBuildFinished(null);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
isFirtCompilation = false;
|
|
72
|
+
}
|
|
73
|
+
resolve({});
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
await onBuildFinished(err);
|
|
77
|
+
isFirtCompilation = false;
|
|
78
|
+
reject(err);
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
doneCallback();
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
async stop() {
|
|
87
|
+
return this.server.stop();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
exports.NativeUITunnelServer = NativeUITunnelServer;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { RequestHandler } from 'http-proxy-middleware';
|
|
1
3
|
import { Resource, Logger } from '@forge/cli-shared';
|
|
2
|
-
import {
|
|
4
|
+
import { CSPDetails } from '@forge/csp';
|
|
3
5
|
import type { Permissions, Remotes } from '@forge/manifest';
|
|
4
6
|
export interface ResourceTunnelServerArgs extends Resource {
|
|
5
7
|
port: number;
|
|
@@ -8,18 +10,14 @@ export interface ResourceTunnelServerArgs extends Resource {
|
|
|
8
10
|
cspReporterServerPort: number;
|
|
9
11
|
remotes: Remotes;
|
|
10
12
|
}
|
|
11
|
-
export declare
|
|
12
|
-
|
|
13
|
-
readonly
|
|
14
|
-
readonly
|
|
15
|
-
readonly
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
private socket;
|
|
20
|
-
private cspReporterServerPort;
|
|
21
|
-
constructor({ port, key, path, tunnel, permissions, remotes, logger, cspReporterServerPort }: ResourceTunnelServerArgs);
|
|
22
|
-
getApp(): Express;
|
|
13
|
+
export declare const TUNNEL_LOCALHOST: string;
|
|
14
|
+
export declare abstract class ResourceTunnelServer {
|
|
15
|
+
protected readonly port: number;
|
|
16
|
+
protected readonly key: string;
|
|
17
|
+
protected readonly path: string;
|
|
18
|
+
protected readonly logger: Logger;
|
|
19
|
+
protected cspReporterServerPort: number;
|
|
20
|
+
constructor({ port, key, path, cspReporterServerPort, logger }: ResourceTunnelServerArgs);
|
|
23
21
|
static transformPermissionsWithRemotes(permissions: Permissions, remotes: Remotes): {
|
|
24
22
|
external: {
|
|
25
23
|
fetch: {
|
|
@@ -37,14 +35,10 @@ export declare class ResourceTunnelServer {
|
|
|
37
35
|
scopes?: import("packages/forge-manifest/out/schema/manifest").Scopes | undefined;
|
|
38
36
|
content?: import("packages/forge-manifest/out/schema/manifest").Content1 | undefined;
|
|
39
37
|
};
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
private getCspHeader;
|
|
46
|
-
private injectGlobalBridgeScript;
|
|
47
|
-
private injectIframeResizerScript;
|
|
48
|
-
private getCustomUIResourceMiddleware;
|
|
38
|
+
protected logFileServed(reqUrl: string, textDecorator: (input: string) => string): void;
|
|
39
|
+
protected getCspHeader: (existingCsp: CSPDetails) => string;
|
|
40
|
+
protected injectGlobalBridgeScript: (htmlContent: Buffer) => Buffer;
|
|
41
|
+
protected injectIframeResizerScript: (htmlContent: Buffer) => Buffer;
|
|
42
|
+
protected getCustomUIHtmlTransformMiddleware: (permissions: Permissions, remotes: Remotes) => RequestHandler;
|
|
49
43
|
}
|
|
50
44
|
//# sourceMappingURL=resource-tunnel-server.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resource-tunnel-server.d.ts","sourceRoot":"","sources":["../../../src/tunnelling/servers/resource-tunnel-server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"resource-tunnel-server.d.ts","sourceRoot":"","sources":["../../../src/tunnelling/servers/resource-tunnel-server.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EACL,QAAQ,EAMR,MAAM,EAEP,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAA6C,MAAM,YAAY,CAAC;AACnF,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAG5D,MAAM,WAAW,wBAAyB,SAAQ,QAAQ;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,WAAW,CAAC;IACzB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,eAAO,MAAM,gBAAgB,QAAsE,CAAC;AAEpG,8BAAsB,oBAAoB;IACxC,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAChC,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAC/B,SAAS,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAChC,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAClC,SAAS,CAAC,qBAAqB,EAAE,MAAM,CAAC;gBAE5B,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,qBAAqB,EAAE,MAAM,EAAE,EAAE,wBAAwB;IAQxF,MAAM,CAAC,+BAA+B,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO;;;;;;;;;;;;;;;;;IAajF,SAAS,CAAC,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI;IAMvF,SAAS,CAAC,YAAY,gBAAiB,UAAU,KAAG,MAAM,CAO1C;IAEhB,SAAS,CAAC,wBAAwB,gBAAiB,MAAM,YAGpD;IAEL,SAAS,CAAC,yBAAyB,gBAAiB,MAAM,YAGrD;IAEL,SAAS,CAAC,kCAAkC,gBAAiB,WAAW,uBAAqB,cAAc,CAqBpG;CACR"}
|
|
@@ -1,19 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ResourceTunnelServer = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
3
|
+
exports.ResourceTunnelServer = exports.TUNNEL_LOCALHOST = void 0;
|
|
5
4
|
const cli_shared_1 = require("@forge/cli-shared");
|
|
6
|
-
const express_1 = tslib_1.__importDefault(require("express"));
|
|
7
|
-
const http_proxy_middleware_1 = require("http-proxy-middleware");
|
|
8
5
|
const csp_1 = require("@forge/csp");
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
(function (ConnectionErrorCode) {
|
|
12
|
-
ConnectionErrorCode["REFUSED"] = "ECONNREFUSED";
|
|
13
|
-
})(ConnectionErrorCode || (ConnectionErrorCode = {}));
|
|
14
|
-
const HOST = process.env.FORGE_DEV_TUNNEL ? 'localhost' : 'host.docker.internal';
|
|
6
|
+
const express_intercept_1 = require("express-intercept");
|
|
7
|
+
exports.TUNNEL_LOCALHOST = process.env.FORGE_DEV_TUNNEL ? 'localhost' : 'host.docker.internal';
|
|
15
8
|
class ResourceTunnelServer {
|
|
16
|
-
constructor({ port, key, path,
|
|
9
|
+
constructor({ port, key, path, cspReporterServerPort, logger }) {
|
|
17
10
|
this.getCspHeader = (existingCsp) => new csp_1.CSPInjectionService()
|
|
18
11
|
.getInjectableCSP(existingCsp, (0, cli_shared_1.getEnvironment)(cli_shared_1.CDNEnvironments), `http://localhost:${this.cspReporterServerPort}`)
|
|
19
12
|
.join('; ');
|
|
@@ -23,11 +16,11 @@ class ResourceTunnelServer {
|
|
|
23
16
|
this.injectIframeResizerScript = (htmlContent) => new cli_shared_1.IframeResizerScriptService().injectIframeResizer(htmlContent, () => {
|
|
24
17
|
throw new Error('Malformed HTML document');
|
|
25
18
|
});
|
|
26
|
-
this.
|
|
27
|
-
|
|
28
|
-
|
|
19
|
+
this.getCustomUIHtmlTransformMiddleware = (permissions, remotes) => (0, express_intercept_1.responseHandler)()
|
|
20
|
+
.if((res) => /html/i.test(res.get('content-type')))
|
|
21
|
+
.replaceBuffer((body, _, res) => {
|
|
22
|
+
if (!res)
|
|
29
23
|
return body;
|
|
30
|
-
res.removeHeader('content-length');
|
|
31
24
|
const htmlContentWithIframeResizerScript = this.injectIframeResizerScript(body);
|
|
32
25
|
const htmlContentWithBridgeScript = this.injectGlobalBridgeScript(htmlContentWithIframeResizerScript);
|
|
33
26
|
const cspDetails = new csp_1.CSPProcessingService({ info: () => { } }).getCspDetails(htmlContentWithBridgeScript, ResourceTunnelServer.transformPermissionsWithRemotes(permissions, remotes));
|
|
@@ -39,42 +32,6 @@ class ResourceTunnelServer {
|
|
|
39
32
|
this.path = path;
|
|
40
33
|
this.logger = logger;
|
|
41
34
|
this.cspReporterServerPort = cspReporterServerPort;
|
|
42
|
-
this.app = (0, express_1.default)();
|
|
43
|
-
this.app.use(this.getCustomUIResourceMiddleware(permissions, remotes));
|
|
44
|
-
if (tunnel) {
|
|
45
|
-
const { port: tunnelPort } = tunnel;
|
|
46
|
-
this.proxy = (0, http_proxy_middleware_1.createProxyMiddleware)({
|
|
47
|
-
target: `http://${HOST}:${tunnelPort}`,
|
|
48
|
-
ws: true,
|
|
49
|
-
logLevel: 'info',
|
|
50
|
-
logProvider: () => {
|
|
51
|
-
return {
|
|
52
|
-
log: this.logger.trace,
|
|
53
|
-
debug: this.logger.trace,
|
|
54
|
-
info: this.logger.trace,
|
|
55
|
-
warn: this.logger.warn,
|
|
56
|
-
error: this.logger.error
|
|
57
|
-
};
|
|
58
|
-
},
|
|
59
|
-
onError: (err, req, res) => {
|
|
60
|
-
this.handleProxyDestinationNotStarted(err, req.url, res, tunnelPort);
|
|
61
|
-
},
|
|
62
|
-
onProxyReq: (_proxyReq, req) => {
|
|
63
|
-
this.logFileServed(req.url, (input) => cli_shared_1.Text.tunnel.customUI.fileProxied(input, this.key, tunnelPort));
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
this.app.use('/', this.proxy);
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
this.app.use((req, _res, next) => {
|
|
70
|
-
this.logFileServed(req.url, (input) => cli_shared_1.Text.tunnel.customUI.fileServed(input, this.key));
|
|
71
|
-
next();
|
|
72
|
-
});
|
|
73
|
-
this.app.use(express_1.default.static(this.path));
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
getApp() {
|
|
77
|
-
return this.app;
|
|
78
35
|
}
|
|
79
36
|
static transformPermissionsWithRemotes(permissions, remotes) {
|
|
80
37
|
var _a, _b, _c, _d, _e;
|
|
@@ -86,45 +43,10 @@ class ResourceTunnelServer {
|
|
|
86
43
|
}).filter((item) => typeof item === 'string')) !== null && _d !== void 0 ? _d : undefined;
|
|
87
44
|
return Object.assign(Object.assign({}, permissions), { external: Object.assign(Object.assign({}, permissions.external), { fetch: Object.assign(Object.assign({}, (_e = permissions.external) === null || _e === void 0 ? void 0 : _e.fetch), { client }) }) });
|
|
88
45
|
}
|
|
89
|
-
async start() {
|
|
90
|
-
return new Promise((resolve) => {
|
|
91
|
-
this.server = this.app.listen(this.port, resolve);
|
|
92
|
-
this.server.on('upgrade', (req, socket, head) => this.handleWebsocketUpgrade(req, socket, head));
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
async stop() {
|
|
96
|
-
if (this.socket) {
|
|
97
|
-
this.socket.end();
|
|
98
|
-
}
|
|
99
|
-
return new Promise((resolve, reject) => {
|
|
100
|
-
if (!this.server) {
|
|
101
|
-
return resolve();
|
|
102
|
-
}
|
|
103
|
-
this.server.close((err) => (err ? reject(err) : resolve()));
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
46
|
logFileServed(reqUrl, textDecorator) {
|
|
107
47
|
if (reqUrl !== '/' && reqUrl !== '/index.html')
|
|
108
48
|
return;
|
|
109
49
|
this.logger.info(cli_shared_1.LogColor.trace(textDecorator('index.html')));
|
|
110
50
|
}
|
|
111
|
-
handleProxyDestinationNotStarted(err, reqUrl, res, tunnelPort) {
|
|
112
|
-
if ((err === null || err === void 0 ? void 0 : err.code) !== ConnectionErrorCode.REFUSED || (reqUrl !== '/' && reqUrl !== 'index.html')) {
|
|
113
|
-
this.logger.error(err);
|
|
114
|
-
return;
|
|
115
|
-
}
|
|
116
|
-
res.writeHead(500, {
|
|
117
|
-
'Content-Type': 'text/plain'
|
|
118
|
-
});
|
|
119
|
-
this.logger.error(new Error(cli_shared_1.Text.tunnel.error.serverNotStartedOnPort(tunnelPort)));
|
|
120
|
-
res.end(cli_shared_1.Text.tunnel.error.serverNotStartedOnPort(tunnelPort));
|
|
121
|
-
}
|
|
122
|
-
handleWebsocketUpgrade(req, socket, head) {
|
|
123
|
-
var _a;
|
|
124
|
-
this.socket = socket;
|
|
125
|
-
if ((_a = this.proxy) === null || _a === void 0 ? void 0 : _a.upgrade) {
|
|
126
|
-
return this.proxy.upgrade(req, socket, head);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
51
|
}
|
|
130
52
|
exports.ResourceTunnelServer = ResourceTunnelServer;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forge/tunnel",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0-next.4",
|
|
4
4
|
"description": "Tunnel functionality for Forge CLI",
|
|
5
5
|
"author": "Atlassian",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -16,24 +16,24 @@
|
|
|
16
16
|
"postbuild": "chmod +x out/*.js"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@forge/bundler": "4.0
|
|
20
|
-
"@forge/cli-shared": "3.4.0-next.
|
|
19
|
+
"@forge/bundler": "4.1.0-next.2",
|
|
20
|
+
"@forge/cli-shared": "3.4.0-next.1",
|
|
21
21
|
"@forge/csp": "^2.0.1",
|
|
22
22
|
"@forge/isolated-vm": "3.3.10",
|
|
23
|
-
"@forge/runtime": "2.6.0-next.
|
|
23
|
+
"@forge/runtime": "2.6.0-next.3",
|
|
24
24
|
"express": "^4.17.1",
|
|
25
|
-
"express-
|
|
25
|
+
"express-intercept": "^0.8.10",
|
|
26
26
|
"http-proxy-middleware": "^1.0.6",
|
|
27
27
|
"ngrok": "^4.3.1",
|
|
28
28
|
"node-cache": "^5.1.2",
|
|
29
29
|
"tmp": "^0.1.0",
|
|
30
30
|
"tslib": "^2.4.0",
|
|
31
|
-
"uuid": "^3.4.0"
|
|
31
|
+
"uuid": "^3.4.0",
|
|
32
|
+
"webpack-dev-server": "^4.11.1"
|
|
32
33
|
},
|
|
33
34
|
"devDependencies": {
|
|
34
35
|
"@forge/manifest": "^4.5.1",
|
|
35
36
|
"@types/express": "^4.17.2",
|
|
36
|
-
"@types/express-mung": "^0.5.2",
|
|
37
37
|
"@types/jest": "^29.1.2",
|
|
38
38
|
"@types/node": "^12.12.63",
|
|
39
39
|
"@types/node-fetch": "^2.5.7",
|