@forge/tunnel 5.1.0 → 5.2.0-next.0

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # @forge/tunnel
2
2
 
3
+ ## 5.2.0-next.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 35b01cd: Move tunnel to Cloudflare
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [35b01cd]
12
+ - @forge/cli-shared@4.2.0-next.0
13
+ - @forge/bundler@4.16.1-next.0
14
+
3
15
  ## 5.1.0
4
16
 
5
17
  ### Minor Changes
@@ -1 +1 @@
1
- {"version":3,"file":"start-tunnel-command.d.ts","sourceRoot":"","sources":["../../src/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,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAChH,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,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;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,EAAE,aAAa,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1F;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,CAe3B;IAEF,OAAO,CAAC,gCAAgC,CAmCtC;IAEW,OAAO,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAoD9E"}
1
+ {"version":3,"file":"start-tunnel-command.d.ts","sourceRoot":"","sources":["../../src/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,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAChH,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,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC1C;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,EAAE,aAAa,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1F;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,CA0B3B;IAEF,OAAO,CAAC,gCAAgC,CAmCtC;IAEW,OAAO,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAyD9E"}
@@ -30,10 +30,17 @@ class StartTunnelCommand {
30
30
  (_a = this.cspReporterServer) === null || _a === void 0 ? void 0 : _a.stop()
31
31
  ]);
32
32
  };
33
- this.startFaaSTunnelServer = async ({ port, tunnelConfigPath }) => {
33
+ this.startFaaSTunnelServer = async ({ port, tunnelConfigPath, appId, environmentKey }) => {
34
34
  const { permissions = {}, remotes = [] } = await this.configFile.readConfig();
35
35
  const serverInfo = await this.devServer.start(port, permissions, remotes);
36
- const faasTunnelUrl = await this.tunnelFactory.establishTunnel({ port: serverInfo.port, tunnelConfigPath });
36
+ const { id, token, url } = await this.tunnelClient.setupTunnel(appId, environmentKey);
37
+ const faasTunnelUrl = await this.tunnelFactory.establishTunnel({
38
+ port: serverInfo.port,
39
+ tunnelConfigPath,
40
+ id,
41
+ token,
42
+ tunnelUrl: url
43
+ });
37
44
  return Object.assign(Object.assign({}, serverInfo), { tunnelUrl: faasTunnelUrl });
38
45
  };
39
46
  this.startResourceBasedTunnelsServers = async (resourceDetails, options) => {
@@ -60,7 +67,12 @@ class StartTunnelCommand {
60
67
  const { port, environmentKey } = options;
61
68
  const allResources = await this.configFile.getResources();
62
69
  try {
63
- const faasTunnelServer = await this.startFaaSTunnelServer({ port, tunnelConfigPath: options.ngrokConfig });
70
+ const faasTunnelServer = await this.startFaaSTunnelServer({
71
+ port,
72
+ tunnelConfigPath: options.ngrokConfig,
73
+ appId,
74
+ environmentKey
75
+ });
64
76
  const customUITunnelsServers = await this.startResourceBasedTunnelsServers(allResources, options);
65
77
  const tunnelDefinitions = {
66
78
  faasTunnelUrl: faasTunnelServer.tunnelUrl,
@@ -8,13 +8,20 @@ export interface TunnelDefinitions {
8
8
  tunnelUrl: URL;
9
9
  }[];
10
10
  }
11
+ export interface TunnelSetup {
12
+ token: string | null | undefined;
13
+ id: string | null | undefined;
14
+ url: string | null | undefined;
15
+ }
11
16
  export interface TunnelClient {
17
+ setupTunnel(appId: string, environmentKey: string): Promise<TunnelSetup>;
12
18
  createAppTunnels(appId: string, environmentKey: string, tunnelDefinitions: TunnelDefinitions): Promise<string | null | undefined>;
13
19
  deleteTunnels(appId: string, environmentKey: string): Promise<void>;
14
20
  }
15
21
  export declare class TunnelGraphqlClient implements TunnelClient {
16
22
  private readonly graphqlClient;
17
23
  constructor(graphqlClient: GraphQLClient);
24
+ setupTunnel(appId: string, environmentKey: string): Promise<TunnelSetup>;
18
25
  createAppTunnels(appId: string, environmentKey: string, tunnelDefinitions: TunnelDefinitions): Promise<string | null | undefined>;
19
26
  deleteTunnels(appId: string, environmentKey: string): Promise<void>;
20
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tunnel-graphql-client.d.ts","sourceRoot":"","sources":["../../src/graphql/tunnel-graphql-client.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,OAAO,EACL,aAAa,EAKd,MAAM,mBAAmB,CAAC;AAqB3B,MAAM,WAAW,iBAAiB;IAChC,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,QAAQ,CAAC,EAAE;QACT,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,GAAG,CAAC;KAChB,EAAE,CAAC;CACL;AAED,MAAM,WAAW,YAAY;IAC3B,gBAAgB,CACd,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,MAAM,EACtB,iBAAiB,EAAE,iBAAiB,GACnC,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACtC,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrE;AAED,qBAAa,mBAAoB,YAAW,YAAY;IAC1C,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAAb,aAAa,EAAE,aAAa;IAEnD,gBAAgB,CACpB,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,MAAM,EACtB,iBAAiB,EAAE,iBAAiB,GACnC,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IA0C/B,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAsC1E"}
1
+ {"version":3,"file":"tunnel-graphql-client.d.ts","sourceRoot":"","sources":["../../src/graphql/tunnel-graphql-client.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,OAAO,EACL,aAAa,EAMd,MAAM,mBAAmB,CAAC;AA8B3B,MAAM,WAAW,iBAAiB;IAChC,aAAa,CAAC,EAAE,GAAG,CAAC;IACpB,QAAQ,CAAC,EAAE;QACT,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,GAAG,CAAC;KAChB,EAAE,CAAC;CACL;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACjC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC9B,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACzE,gBAAgB,CACd,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,MAAM,EACtB,iBAAiB,EAAE,iBAAiB,GACnC,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACtC,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrE;AAED,qBAAa,mBAAoB,YAAW,YAAY;IAC1C,OAAO,CAAC,QAAQ,CAAC,aAAa;gBAAb,aAAa,EAAE,aAAa;IAEnD,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IA8CxE,gBAAgB,CACpB,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,MAAM,EACtB,iBAAiB,EAAE,iBAAiB,GACnC,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IA0C/B,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAsC1E"}
@@ -8,6 +8,11 @@ class CreateAppTunnelError extends cli_shared_1.GraphQlMutationError {
8
8
  super(cli_shared_2.Text.tunnel.error.create(message), { requestId, code, statusCode });
9
9
  }
10
10
  }
11
+ class RegisterAppTunnelError extends cli_shared_1.GraphQlMutationError {
12
+ constructor(message, { requestId, code, statusCode }) {
13
+ super(cli_shared_2.Text.tunnel.error.create(message), { requestId, code, statusCode });
14
+ }
15
+ }
11
16
  class DeleteAppTunnelError extends cli_shared_1.GraphQlMutationError {
12
17
  constructor(message, { requestId, code, statusCode }) {
13
18
  super(cli_shared_2.Text.tunnel.error.delete(message), { requestId, code, statusCode });
@@ -17,6 +22,44 @@ class TunnelGraphqlClient {
17
22
  constructor(graphqlClient) {
18
23
  this.graphqlClient = graphqlClient;
19
24
  }
25
+ async setupTunnel(appId, environmentKey) {
26
+ const mutation = `
27
+ mutation forge_cli_setupApplicationTunnel($input: RegisterTunnelInput!) {
28
+ registerTunnel(input: $input) {
29
+ success
30
+ errors {
31
+ message
32
+ extensions {
33
+ errorType
34
+ statusCode
35
+ }
36
+ }
37
+ tunnelId
38
+ tunnelToken
39
+ tunnelUrl
40
+ }
41
+ }
42
+ `;
43
+ const { response: { registerTunnel: { success, errors, tunnelId, tunnelToken, tunnelUrl } }, requestId } = await this.graphqlClient.mutate(mutation, {
44
+ input: {
45
+ appId,
46
+ environmentKey
47
+ }
48
+ });
49
+ const error = (0, cli_shared_1.getError)(errors);
50
+ if (!success) {
51
+ throw new RegisterAppTunnelError(`${error.message} (requestId: ${requestId || 'unknown'})`, {
52
+ requestId,
53
+ code: error.code,
54
+ statusCode: error.statusCode
55
+ });
56
+ }
57
+ return {
58
+ id: tunnelId,
59
+ token: tunnelToken,
60
+ url: tunnelUrl
61
+ };
62
+ }
20
63
  async createAppTunnels(appId, environmentKey, tunnelDefinitions) {
21
64
  const mutation = `
22
65
  mutation forge_cli_createApplicationTunnels($input: CreateAppTunnelsInput!) {
@@ -1,11 +1,19 @@
1
1
  /// <reference types="node" resolution-mode="require"/>
2
2
  import { URL } from 'url';
3
- import { BaseError, Logger } from '@forge/cli-shared';
3
+ import { BaseError, FeatureFlagService, Logger } from '@forge/cli-shared';
4
+ export declare type NgrokTunnelConfig = {
5
+ tunnelConfigPath: string | undefined;
6
+ };
7
+ export declare type CloudflareTunnelConfig = {
8
+ token: string | null | undefined;
9
+ id: string | null | undefined;
10
+ tunnelUrl: string | null | undefined;
11
+ };
12
+ export declare type TunnelConfig = {
13
+ port: number;
14
+ } & NgrokTunnelConfig & CloudflareTunnelConfig;
4
15
  export interface CreateTunnelService {
5
- establishTunnel({ port, tunnelConfigPath }: {
6
- port: number;
7
- tunnelConfigPath: string | undefined;
8
- }): Promise<URL>;
16
+ establishTunnel({ port, tunnelConfigPath, token, id, tunnelUrl }: TunnelConfig): Promise<URL>;
9
17
  closeTunnel(): Promise<void>;
10
18
  }
11
19
  export declare const USER_NGROK_ERRORS: string[];
@@ -13,14 +21,29 @@ export declare class NgrokError extends BaseError {
13
21
  constructor(message?: string);
14
22
  isUserError(): boolean;
15
23
  }
24
+ export declare class CloudflareError extends BaseError {
25
+ }
26
+ export declare class TunnelServiceFacade implements CreateTunnelService {
27
+ private readonly featureFlagService;
28
+ private readonly logger;
29
+ private instance;
30
+ constructor(featureFlagService: FeatureFlagService, logger: Logger);
31
+ private getInstance;
32
+ establishTunnel({ port, tunnelConfigPath, id, token, tunnelUrl }: TunnelConfig): Promise<URL>;
33
+ closeTunnel(): Promise<void>;
34
+ }
35
+ export declare class CloudflareCreateTunnelService implements CreateTunnelService {
36
+ private readonly logger;
37
+ private stopFunction;
38
+ constructor(logger: Logger);
39
+ establishTunnel({ port, id, token, tunnelUrl }: TunnelConfig): Promise<URL>;
40
+ closeTunnel(): Promise<void>;
41
+ }
16
42
  export declare class NgrokCreateTunnelService implements CreateTunnelService {
17
43
  private readonly logger;
18
44
  private endpoint;
19
45
  constructor(logger: Logger);
20
- establishTunnel({ port, tunnelConfigPath }: {
21
- port: number;
22
- tunnelConfigPath: string | undefined;
23
- }): Promise<URL>;
46
+ establishTunnel({ port, tunnelConfigPath }: TunnelConfig): Promise<URL>;
24
47
  closeTunnel(): Promise<void>;
25
48
  }
26
49
  //# sourceMappingURL=create-tunnel-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-tunnel-service.d.ts","sourceRoot":"","sources":["../../src/services/create-tunnel-service.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,OAAO,EAAE,SAAS,EAAE,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAG5D,MAAM,WAAW,mBAAmB;IAClC,eAAe,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAClH,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAGD,eAAO,MAAM,iBAAiB,UAiB7B,CAAC;AACF,qBAAa,UAAW,SAAQ,SAAS;gBAC3B,OAAO,CAAC,EAAE,MAAM;IAIrB,WAAW;CAGnB;AAED,qBAAa,wBAAyB,YAAW,mBAAmB;IAGtD,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,OAAO,CAAC,QAAQ,CAAqB;gBAER,MAAM,EAAE,MAAM;IAE9B,eAAe,CAAC,EAC3B,IAAI,EACJ,gBAAgB,EACjB,EAAE;QACD,IAAI,EAAE,MAAM,CAAC;QACb,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;KACtC,GAAG,OAAO,CAAC,GAAG,CAAC;IAsCH,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;CAkB1C"}
1
+ {"version":3,"file":"create-tunnel-service.d.ts","sourceRoot":"","sources":["../../src/services/create-tunnel-service.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAGhF,oBAAY,iBAAiB,GAAG;IAC9B,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC,CAAC;AAEF,oBAAY,sBAAsB,GAAG;IACnC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACjC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC9B,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACtC,CAAC;AAEF,oBAAY,YAAY,GAAG;IACzB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,iBAAiB,GACnB,sBAAsB,CAAC;AAEzB,MAAM,WAAW,mBAAmB;IAClC,eAAe,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAC9F,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAGD,eAAO,MAAM,iBAAiB,UAiB7B,CAAC;AACF,qBAAa,UAAW,SAAQ,SAAS;gBAC3B,OAAO,CAAC,EAAE,MAAM;IAIrB,WAAW;CAGnB;AAED,qBAAa,eAAgB,SAAQ,SAAS;CAAG;AAKjD,qBAAa,mBAAoB,YAAW,mBAAmB;IAI3D,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJzB,OAAO,CAAC,QAAQ,CAAkC;gBAG/B,kBAAkB,EAAE,kBAAkB,EACtC,MAAM,EAAE,MAAM;YAGnB,WAAW;IASZ,eAAe,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC;IAI7F,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;CAG1C;AAED,qBAAa,6BAA8B,YAAW,mBAAmB;IAG3D,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,OAAO,CAAC,YAAY,CAA0E;gBAEjE,MAAM,EAAE,MAAM;IAE9B,eAAe,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC;IAsB3E,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ1C;AAED,qBAAa,wBAAyB,YAAW,mBAAmB;IAGtD,OAAO,CAAC,QAAQ,CAAC,MAAM;IAFnC,OAAO,CAAC,QAAQ,CAAqB;gBAER,MAAM,EAAE,MAAM;IAE9B,eAAe,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC;IAsCvE,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;CAkB1C"}
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.NgrokCreateTunnelService = exports.NgrokError = exports.USER_NGROK_ERRORS = void 0;
3
+ exports.NgrokCreateTunnelService = exports.CloudflareCreateTunnelService = exports.TunnelServiceFacade = exports.CloudflareError = exports.NgrokError = exports.USER_NGROK_ERRORS = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const ngrok = tslib_1.__importStar(require("ngrok"));
6
+ const cloudflared_1 = require("cloudflared");
6
7
  const url_1 = require("url");
7
8
  const cli_shared_1 = require("@forge/cli-shared");
8
9
  const path_1 = tslib_1.__importDefault(require("path"));
@@ -33,6 +34,61 @@ class NgrokError extends cli_shared_1.BaseError {
33
34
  }
34
35
  }
35
36
  exports.NgrokError = NgrokError;
37
+ class CloudflareError extends cli_shared_1.BaseError {
38
+ }
39
+ exports.CloudflareError = CloudflareError;
40
+ class TunnelServiceFacade {
41
+ constructor(featureFlagService, logger) {
42
+ this.featureFlagService = featureFlagService;
43
+ this.logger = logger;
44
+ }
45
+ async getInstance() {
46
+ if (!this.instance) {
47
+ this.instance = (await this.featureFlagService.isCloudflareTunnelEnabled())
48
+ ? new CloudflareCreateTunnelService(this.logger)
49
+ : new NgrokCreateTunnelService(this.logger);
50
+ }
51
+ return this.instance;
52
+ }
53
+ async establishTunnel({ port, tunnelConfigPath, id, token, tunnelUrl }) {
54
+ return (await this.getInstance()).establishTunnel({ port, tunnelConfigPath, id, token, tunnelUrl });
55
+ }
56
+ async closeTunnel() {
57
+ return (await this.getInstance()).closeTunnel();
58
+ }
59
+ }
60
+ exports.TunnelServiceFacade = TunnelServiceFacade;
61
+ class CloudflareCreateTunnelService {
62
+ constructor(logger) {
63
+ this.logger = logger;
64
+ }
65
+ async establishTunnel({ port, id, token, tunnelUrl }) {
66
+ if (!id || !token || !tunnelUrl) {
67
+ throw new CloudflareError(undefined, 'Missing configuration to create tunnel');
68
+ }
69
+ const options = {
70
+ run: null,
71
+ '--token': token,
72
+ '--url': `localhost:${port}`
73
+ };
74
+ options[id] = null;
75
+ const { connections, stop } = (0, cloudflared_1.tunnel)(options);
76
+ await Promise.all(connections);
77
+ this.stopFunction = stop;
78
+ this.logger.debug(cli_shared_1.Text.tunnel.startedTunnel(tunnelUrl));
79
+ return new url_1.URL(tunnelUrl);
80
+ }
81
+ async closeTunnel() {
82
+ if (this.stopFunction) {
83
+ try {
84
+ this.stopFunction('SIGKILL');
85
+ }
86
+ catch (_a) { }
87
+ this.stopFunction = undefined;
88
+ }
89
+ }
90
+ }
91
+ exports.CloudflareCreateTunnelService = CloudflareCreateTunnelService;
36
92
  class NgrokCreateTunnelService {
37
93
  constructor(logger) {
38
94
  this.logger = logger;
@@ -1,14 +1,18 @@
1
- import { TunnelClient, TunnelDefinitions } from '../graphql';
1
+ import { TunnelClient, TunnelDefinitions, TunnelSetup } from '../graphql';
2
+ import { FeatureFlagService } from '@forge/cli-shared';
2
3
  export interface RegisterTunnelService {
4
+ setupTunnel(appId: string, environmentKey: string): Promise<TunnelSetup>;
3
5
  registerTunnels(appId: string, environmentKey: string, tunnelDefinitions: TunnelDefinitions): Promise<void>;
4
6
  unregisterTunnels(appId: string, environmentKey: string): Promise<void>;
5
7
  }
6
8
  export declare class RegisterTunnelServiceImpl implements RegisterTunnelService {
7
9
  private readonly tunnelClient;
8
- constructor(tunnelClient: TunnelClient);
10
+ private readonly featureFlagService;
11
+ constructor(tunnelClient: TunnelClient, featureFlagService: FeatureFlagService);
9
12
  private keepAliveHandler;
10
13
  private keepAliveActive;
11
14
  registerTunnels(appId: string, environmentKey: string, tunnelDefinitions: TunnelDefinitions): Promise<void>;
15
+ setupTunnel(appId: string, environmentKey: string): Promise<TunnelSetup>;
12
16
  unregisterTunnels(appId: string, environmentKey: string): Promise<void>;
13
17
  private keepTunnelsAlive;
14
18
  private getTTL;
@@ -1 +1 @@
1
- {"version":3,"file":"register-tunnel-service.d.ts","sourceRoot":"","sources":["../../src/services/register-tunnel-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAI7D,MAAM,WAAW,qBAAqB;IACpC,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,iBAAiB,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5G,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzE;AAED,qBAAa,yBAA0B,YAAW,qBAAqB;IACzD,OAAO,CAAC,QAAQ,CAAC,YAAY;gBAAZ,YAAY,EAAE,YAAY;IAIvD,OAAO,CAAC,gBAAgB,CAA6B;IACrD,OAAO,CAAC,eAAe,CAAU;IAEpB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,iBAAiB,EAAE,iBAAiB;IAQ3F,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;YAQtD,gBAAgB;IAoB9B,OAAO,CAAC,MAAM;CAaf"}
1
+ {"version":3,"file":"register-tunnel-service.d.ts","sourceRoot":"","sources":["../../src/services/register-tunnel-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAIvD,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACzE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,iBAAiB,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5G,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzE;AAED,qBAAa,yBAA0B,YAAW,qBAAqB;IAEnE,OAAO,CAAC,QAAQ,CAAC,YAAY;IAC7B,OAAO,CAAC,QAAQ,CAAC,kBAAkB;gBADlB,YAAY,EAAE,YAAY,EAC1B,kBAAkB,EAAE,kBAAkB;IAKzD,OAAO,CAAC,gBAAgB,CAA6B;IACrD,OAAO,CAAC,eAAe,CAAU;IAEpB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,iBAAiB,EAAE,iBAAiB;IAQ3F,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;IAWjD,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;YAQtD,gBAAgB;IAoB9B,OAAO,CAAC,MAAM;CAaf"}
@@ -3,8 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RegisterTunnelServiceImpl = void 0;
4
4
  const ONE_DAY = 1000 * 60 * 60 * 24;
5
5
  class RegisterTunnelServiceImpl {
6
- constructor(tunnelClient) {
6
+ constructor(tunnelClient, featureFlagService) {
7
7
  this.tunnelClient = tunnelClient;
8
+ this.featureFlagService = featureFlagService;
8
9
  this.keepAliveActive = true;
9
10
  }
10
11
  async registerTunnels(appId, environmentKey, tunnelDefinitions) {
@@ -14,6 +15,16 @@ class RegisterTunnelServiceImpl {
14
15
  const expiry = await this.tunnelClient.createAppTunnels(appId, environmentKey, tunnelDefinitions);
15
16
  await this.keepTunnelsAlive(appId, environmentKey, tunnelDefinitions, expiry);
16
17
  }
18
+ async setupTunnel(appId, environmentKey) {
19
+ if (await this.featureFlagService.isCloudflareTunnelEnabled()) {
20
+ return await this.tunnelClient.setupTunnel(appId, environmentKey);
21
+ }
22
+ return {
23
+ token: undefined,
24
+ id: undefined,
25
+ url: undefined
26
+ };
27
+ }
17
28
  async unregisterTunnels(appId, environmentKey) {
18
29
  if (this.keepAliveHandler) {
19
30
  clearTimeout(this.keepAliveHandler);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forge/tunnel",
3
- "version": "5.1.0",
3
+ "version": "5.2.0-next.0",
4
4
  "description": "Tunnel functionality for Forge CLI",
5
5
  "author": "Atlassian",
6
6
  "license": "UNLICENSED",
@@ -11,10 +11,11 @@
11
11
  "compile": "tsc -b -v"
12
12
  },
13
13
  "dependencies": {
14
- "@forge/bundler": "4.16.0",
15
- "@forge/cli-shared": "4.1.0",
14
+ "@forge/bundler": "4.16.1-next.0",
15
+ "@forge/cli-shared": "4.2.0-next.0",
16
16
  "@forge/csp": "3.2.1",
17
17
  "@forge/runtime": "5.8.0",
18
+ "cloudflared": "^0.5.1",
18
19
  "express": "^4.18.3",
19
20
  "express-intercept": "^1.1.0",
20
21
  "http-proxy-middleware": "^2.0.6",