@forge/tunnel 2.1.5-next.2 → 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.
Files changed (29) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/out/index.js +2 -2
  3. package/out/tunnelling/command/interactors/function-change-watcher.d.ts.map +1 -1
  4. package/out/tunnelling/command/interactors/function-change-watcher.js +0 -1
  5. package/out/tunnelling/command/interactors/multi-compiler-watcher.d.ts +11 -0
  6. package/out/tunnelling/command/interactors/multi-compiler-watcher.d.ts.map +1 -0
  7. package/out/tunnelling/command/interactors/multi-compiler-watcher.js +19 -0
  8. package/out/tunnelling/command/interactors/tunnel-interactor.d.ts +2 -2
  9. package/out/tunnelling/command/interactors/tunnel-interactor.d.ts.map +1 -1
  10. package/out/tunnelling/command/interactors/tunnel-interactor.js +46 -38
  11. package/out/tunnelling/command/start-tunnel-command.d.ts +2 -1
  12. package/out/tunnelling/command/start-tunnel-command.d.ts.map +1 -1
  13. package/out/tunnelling/command/start-tunnel-command.js +22 -19
  14. package/out/tunnelling/servers/custom-ui-tunnel-server.d.ts +18 -0
  15. package/out/tunnelling/servers/custom-ui-tunnel-server.d.ts.map +1 -0
  16. package/out/tunnelling/servers/custom-ui-tunnel-server.js +102 -0
  17. package/out/tunnelling/servers/dev-server.d.ts +21 -4
  18. package/out/tunnelling/servers/dev-server.d.ts.map +1 -1
  19. package/out/tunnelling/servers/dev-server.js +72 -2
  20. package/out/tunnelling/servers/index.d.ts +2 -0
  21. package/out/tunnelling/servers/index.d.ts.map +1 -1
  22. package/out/tunnelling/servers/index.js +2 -0
  23. package/out/tunnelling/servers/native-ui-tunnel-server.d.ts +11 -0
  24. package/out/tunnelling/servers/native-ui-tunnel-server.d.ts.map +1 -0
  25. package/out/tunnelling/servers/native-ui-tunnel-server.js +90 -0
  26. package/out/tunnelling/servers/resource-tunnel-server.d.ts +16 -22
  27. package/out/tunnelling/servers/resource-tunnel-server.d.ts.map +1 -1
  28. package/out/tunnelling/servers/resource-tunnel-server.js +8 -86
  29. package/package.json +7 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
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
+
16
+ ## 2.1.5-next.3
17
+
18
+ ### Patch Changes
19
+
20
+ - Updated dependencies [e5dd325d]
21
+ - @forge/runtime@2.6.0-next.2
22
+ - @forge/bundler@4.0.3-next.1
23
+
3
24
  ## 2.1.5-next.2
4
25
 
5
26
  ### 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, configFile);
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;CAqBlC"}
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 { ConfigFile, Logger } from '@forge/cli-shared';
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, configFile: ConfigFile) => Promise<WatcherMonitor | undefined>;
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":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAY,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAI5D,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;IAgCT,QAAQ,sBACM,iBAAiB,cACxB,UAAU,KACrB,QAAQ,cAAc,GAAG,SAAS,CAAC,CAiDpC;CACH"}
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 index_1 = require("../../index");
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, configFile) => {
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 handlers = await configFile.getAppHandlers();
19
- const currentDirectory = process.cwd();
20
- const entryPoints = [];
21
- for (const handler of handlers) {
22
- entryPoints.push({
23
- name: handler,
24
- path: path_1.default.join(currentDirectory, 'src', handler)
25
- });
26
- }
27
- if (entryPoints.length > 0) {
28
- return (0, bundler_1.watch)(entryPoints, (0, index_1.isInspectorEnabled)(), async (err, output) => {
29
- if (err) {
30
- this.logger.error(err);
31
- }
32
- else if (output) {
33
- this.logger.info(cli_shared_1.LogColor.trace(cli_shared_1.Text.tunnel.bundlingSucceeded));
34
- await reloadSandboxes(output);
35
- this.logger.info('');
36
- this.logger.info(cli_shared_1.Text.tunnel.startedServer(localPort, this.logger.debugEnabled) + '\n');
37
- }
38
- }, async (compiler, preBundleSteps, done) => {
39
- try {
40
- this.logger.info('');
41
- this.logger.info(cli_shared_1.Text.bundle.detectedChanges);
42
- await preBundleSteps();
43
- this.logger.info(cli_shared_1.Text.tunnel.preBundleTask(cli_shared_1.Text.tunnel.bundlingHeader));
44
- done();
45
- }
46
- catch (err) {
47
- throw err;
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 startCustomUITunnelServers;
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,EAAQ,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAAE,SAAS,EAAqB,MAAM,gBAAgB,CAAC;AAI9D,OAAO,EAAE,iBAAiB,EAA2C,MAAM,YAAY,CAAC;AACxF,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;AAEzE,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,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,CAA4C;IACjE,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,0BAA0B,CAiChC;IAEW,OAAO,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAwC9E"}
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 localPort = await this.devServer.start(port, permissions, remotes);
37
- const faasTunnelUrl = await this.tunnelFactory.establishTunnel(localPort);
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.startCustomUITunnelServers = async () => {
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
- this.tunnelServers[key] = new servers_1.ResourceTunnelServer(Object.assign(Object.assign({}, rd), { port, logger: this.logger, cspReporterServerPort: cspReporterPort, permissions,
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
- await this.tunnelServers[key].start();
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.startCustomUITunnelServers();
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 { localPort: faasTunnelServer.port, tunnelDefinitions, inspectorAddress, stopFunction, reloadSandboxes };
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 { Logger } from '@forge/cli-shared';
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<number>;
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<number>;
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;AAC3C,OAAO,EAAE,mBAAmB,EAAe,MAAM,gBAAgB,CAAC;AAElE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAEvD,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACpF,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;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;IAMlD,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAAqB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAL1F,OAAO,CAAC,GAAG,CAAsB;IACjC,OAAO,CAAC,UAAU,CAA0B;IAC5C,OAAO,CAAC,WAAW,CAA0B;IAC7C,OAAO,CAAC,OAAO,CAAsB;gBAER,iBAAiB,EAAE,iBAAiB,EAAmB,MAAM,EAAE,MAAM;IAOrF,KAAK,CAAC,IAAI,SAAI,EAAE,WAAW,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAY9E,IAAI;IAUV,MAAM,IAAI,OAAO,CAAC,WAAW;IAI7B,gBAAgB,EAAE,OAAO,CAAC,OAAO,CAsCtC;CACH"}
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 this.httpServer.address().port;
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,4 +1,6 @@
1
1
  export * from './dev-server';
2
2
  export * from './resource-tunnel-server';
3
+ export * from './custom-ui-tunnel-server';
4
+ export * from './native-ui-tunnel-server';
3
5
  export * from './csp-reporter-server';
4
6
  //# sourceMappingURL=index.d.ts.map
@@ -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 { Express } from 'express';
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 class ResourceTunnelServer {
12
- private readonly port;
13
- readonly key: string;
14
- readonly path: string;
15
- readonly logger: Logger;
16
- private readonly app;
17
- private server;
18
- private readonly proxy;
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
- start(): Promise<void>;
41
- stop(): Promise<void>;
42
- private logFileServed;
43
- private handleProxyDestinationNotStarted;
44
- private handleWebsocketUpgrade;
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":"AAAA,OAAO,EACL,QAAQ,EAMR,MAAM,EAGP,MAAM,mBAAmB,CAAC;AAC3B,OAAgB,EAAE,OAAO,EAAqB,MAAM,SAAS,CAAC;AAM9D,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE5D,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;AAYD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,SAAgB,GAAG,EAAE,MAAM,CAAC;IAC5B,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAU;IAC9B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IACnD,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,qBAAqB,CAAS;gBAE1B,EACV,IAAI,EACJ,GAAG,EACH,IAAI,EACJ,MAAM,EACN,WAAW,EACX,OAAO,EACP,MAAM,EACN,qBAAqB,EACtB,EAAE,wBAAwB;IA0C3B,MAAM,IAAI,OAAO;IAIjB,MAAM,CAAC,+BAA+B,CAAC,WAAW,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO;;;;;;;;;;;;;;;;;IAa3E,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAStB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAc3B,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,gCAAgC;IAoBxC,OAAO,CAAC,sBAAsB;IAQ9B,OAAO,CAAC,YAAY,CAOJ;IAEhB,OAAO,CAAC,wBAAwB,CAG3B;IAEL,OAAO,CAAC,yBAAyB,CAG5B;IAEL,OAAO,CAAC,6BAA6B,CAwBhC;CACN"}
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 express_mung_1 = require("express-mung");
10
- var ConnectionErrorCode;
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, tunnel, permissions, remotes, logger, cspReporterServerPort }) {
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.getCustomUIResourceMiddleware = (permissions, remotes) => (0, express_mung_1.write)((body, _, __, res) => {
27
- const contentType = res.getHeaders()['content-type'];
28
- if (!contentType.startsWith('text/html'))
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.1.5-next.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.3-next.0",
20
- "@forge/cli-shared": "3.4.0-next.0",
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.1",
23
+ "@forge/runtime": "2.6.0-next.3",
24
24
  "express": "^4.17.1",
25
- "express-mung": "^0.5.1",
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",