@dbx-tools/tunnel 0.6.123 → 0.6.125

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.
@@ -16,7 +16,9 @@
16
16
  *
17
17
  * @module
18
18
  */
19
- import type { Interceptor } from "@dbx-tools/appkit";
19
+ import type { Interceptor, InterceptorContext } from "@dbx-tools/appkit";
20
+ import { resolveFrpConfig } from "./frp.ts";
21
+ import { resolvePortrConfig } from "./portr.ts";
20
22
  /** Options for {@link tunnelInterceptor} (each also resolvable from env). */
21
23
  export interface TunnelInterceptorOptions {
22
24
  /** Tunnel clients to run. Env `DBX_TOOLS_TUNNEL_TRANSPORT`; defaults to `portr`. */
@@ -50,6 +52,13 @@ export interface TunnelInterceptorOptions {
50
52
  }
51
53
  /** Public tunnel clients supported by the interceptor and CLI. */
52
54
  export type TunnelTransport = "portr" | "frp" | "both";
55
+ interface TunnelAuxiliary {
56
+ stop(): void;
57
+ }
58
+ interface TunnelRuntime {
59
+ startPortr(config: NonNullable<ReturnType<typeof resolvePortrConfig>>): Promise<TunnelAuxiliary>;
60
+ startFrp(config: NonNullable<ReturnType<typeof resolveFrpConfig>>, ctx: InterceptorContext): Promise<TunnelAuxiliary>;
61
+ }
53
62
  /** Resolve and validate the tunnel transport selector. */
54
63
  export declare function resolveTunnelTransport(transport?: string): TunnelTransport;
55
64
  /**
@@ -67,4 +76,5 @@ export declare function resolveTunnelTransport(transport?: string): TunnelTransp
67
76
  * interceptor: tunnelInterceptor(),
68
77
  * });
69
78
  */
70
- export declare function tunnelInterceptor(options?: TunnelInterceptorOptions): Interceptor;
79
+ export declare function tunnelInterceptor(options?: TunnelInterceptorOptions, runtime?: TunnelRuntime): Interceptor;
80
+ export {};
@@ -21,12 +21,34 @@ import { installFrp, resolveFrpConfig, superviseFrp, writeFrpConfig } from "./fr
21
21
  import { installPortr, resolvePortrConfig, supervisePortr, writePortrConfig } from "./portr.js";
22
22
  import { startPathProxy } from "./path-proxy.js";
23
23
  const logger = log.logger("tunnel:interceptor");
24
+ const defaultRuntime = {
25
+ async startPortr(config) {
26
+ const portrEnv = await installPortr();
27
+ await writePortrConfig(config, portrEnv);
28
+ return supervisePortr(config, portrEnv);
29
+ },
30
+ async startFrp(config, ctx) {
31
+ const pathProxy = config.stripPrefix && config.path !== "/"
32
+ ? await startPathProxy(config.targetPort, config.path)
33
+ : undefined;
34
+ if (pathProxy) {
35
+ config.targetPort = pathProxy.port;
36
+ ctx.onLifecycle("shutdown", () => void pathProxy.close());
37
+ }
38
+ const frpEnv = await installFrp();
39
+ const configPath = await writeFrpConfig(config, frpEnv);
40
+ const supervisor = superviseFrp(config, frpEnv, configPath);
41
+ return {
42
+ stop() {
43
+ supervisor.stop();
44
+ void pathProxy?.close();
45
+ },
46
+ };
47
+ },
48
+ };
24
49
  /** Resolve and validate the tunnel transport selector. */
25
50
  export function resolveTunnelTransport(transport) {
26
- const resolved = transport ??
27
- process.env.DBX_TOOLS_TUNNEL_TRANSPORT ??
28
- process.env.TUNNEL_TRANSPORT ??
29
- "portr";
51
+ const resolved = transport ?? process.env.DBX_TOOLS_TUNNEL_TRANSPORT ?? process.env.TUNNEL_TRANSPORT ?? "portr";
30
52
  if (resolved === "portr" || resolved === "frp" || resolved === "both")
31
53
  return resolved;
32
54
  throw new TypeError(`invalid tunnel transport: ${resolved} (expected portr, frp, or both)`);
@@ -50,14 +72,14 @@ function resolvePublicPort(port) {
50
72
  * interceptor: tunnelInterceptor(),
51
73
  * });
52
74
  */
53
- export function tunnelInterceptor(options = {}) {
75
+ export function tunnelInterceptor(options = {}, runtime = defaultRuntime) {
54
76
  return async (ctx) => {
55
77
  if (ctx.env.databricksHost) {
56
78
  process.env.DATABRICKS_HOST ??= ctx.env.databricksHost;
57
79
  }
58
80
  const port = resolvePublicPort(options.port);
59
81
  const transport = resolveTunnelTransport(options.transport);
60
- const auxiliaries = [];
82
+ const initializers = [];
61
83
  if (transport === "portr" || transport === "both") {
62
84
  const portrConfig = resolvePortrConfig({
63
85
  publicDomain: options.publicDomain,
@@ -65,9 +87,7 @@ export function tunnelInterceptor(options = {}) {
65
87
  port,
66
88
  });
67
89
  if (portrConfig) {
68
- const portrEnv = await installPortr();
69
- await writePortrConfig(portrConfig, portrEnv);
70
- auxiliaries.push(supervisePortr(portrConfig, portrEnv));
90
+ initializers.push(runtime.startPortr(portrConfig));
71
91
  }
72
92
  else {
73
93
  logger.info("portr not configured (requires PORTR_TOKEN and TUNNEL_PUBLIC_DOMAIN)");
@@ -86,32 +106,38 @@ export function tunnelInterceptor(options = {}) {
86
106
  port,
87
107
  });
88
108
  if (frpConfig) {
89
- const pathProxy = frpConfig.stripPrefix && frpConfig.path !== "/"
90
- ? await startPathProxy(port, frpConfig.path)
91
- : undefined;
92
- if (pathProxy) {
93
- frpConfig.targetPort = pathProxy.port;
94
- ctx.onLifecycle("shutdown", () => void pathProxy.close());
95
- }
96
- const frpEnv = await installFrp();
97
- const configPath = await writeFrpConfig(frpConfig, frpEnv);
98
- auxiliaries.push(superviseFrp(frpConfig, frpEnv, configPath));
109
+ initializers.push(runtime.startFrp(frpConfig, ctx));
99
110
  }
100
111
  else {
101
112
  logger.info("frp not configured (requires TUNNEL_PUBLIC_DOMAIN)");
102
113
  }
103
114
  }
104
- if (!auxiliaries.length)
115
+ if (!initializers.length)
105
116
  return;
106
- ctx.onTeardown(() => {
107
- for (const auxiliary of auxiliaries)
108
- auxiliary.stop();
109
- });
110
- ctx.onLifecycle("shutdown", () => {
117
+ const auxiliaries = [];
118
+ let stopped = false;
119
+ const stop = () => {
120
+ stopped = true;
111
121
  for (const auxiliary of auxiliaries)
112
122
  auxiliary.stop();
123
+ };
124
+ ctx.onTeardown(stop);
125
+ ctx.onLifecycle("shutdown", stop);
126
+ void Promise.allSettled(initializers).then((results) => {
127
+ for (const result of results) {
128
+ if (result.status === "rejected") {
129
+ logger.error("tunnel failed to start", { error: result.reason });
130
+ continue;
131
+ }
132
+ if (stopped)
133
+ result.value.stop();
134
+ else
135
+ auxiliaries.push(result.value);
136
+ }
137
+ if (!stopped && auxiliaries.length)
138
+ logger.info(`tunnel bound: ${transport} -> :${port}`);
113
139
  });
114
- logger.info(`tunnel bound: ${transport} -> :${port}`);
140
+ logger.info(`tunnel initialization scheduled: ${transport} -> :${port}`);
115
141
  };
116
142
  }
117
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJjZXB0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW50ZXJjZXB0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBR0gsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsVUFBVSxFQUFFLGdCQUFnQixFQUFFLFlBQVksRUFBRSxjQUFjLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDdEYsT0FBTyxFQUFFLFlBQVksRUFBRSxrQkFBa0IsRUFBRSxjQUFjLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDaEcsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRWpELE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsb0JBQW9CLENBQUMsQ0FBQztBQXFDaEQsMERBQTBEO0FBQzFELE1BQU0sVUFBVSxzQkFBc0IsQ0FBQyxTQUFrQjtJQUN2RCxNQUFNLFFBQVEsR0FDWixTQUFTO1FBQ1QsT0FBTyxDQUFDLEdBQUcsQ0FBQywwQkFBMEI7UUFDdEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0I7UUFDNUIsT0FBTyxDQUFDO0lBQ1YsSUFBSSxRQUFRLEtBQUssT0FBTyxJQUFJLFFBQVEsS0FBSyxLQUFLLElBQUksUUFBUSxLQUFLLE1BQU07UUFBRSxPQUFPLFFBQVEsQ0FBQztJQUN2RixNQUFNLElBQUksU0FBUyxDQUFDLDZCQUE2QixRQUFRLGlDQUFpQyxDQUFDLENBQUM7QUFDOUYsQ0FBQztBQUVELHFGQUFxRjtBQUNyRixTQUFTLGlCQUFpQixDQUFDLElBQWE7SUFDdEMsT0FBTyxJQUFJLElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixDQUFDLElBQUksSUFBSSxDQUFDO0FBQzFFLENBQUM7QUFFRDs7Ozs7Ozs7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SUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNO1lBQUUsT0FBTztRQUNoQyxHQUFHLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNsQixLQUFLLE1BQU0sU0FBUyxJQUFJLFdBQVc7Z0JBQUUsU0FBUyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3hELENBQUMsQ0FBQyxDQUFDO1FBQ0gsR0FBRyxDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsR0FBRyxFQUFFO1lBQy9CLEtBQUssTUFBTSxTQUFTLElBQUksV0FBVztnQkFBRSxTQUFTLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDeEQsQ0FBQyxDQUFDLENBQUM7UUFDSCxNQUFNLENBQUMsSUFBSSxDQUFDLGlCQUFpQixTQUFTLFFBQVEsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUN4RCxDQUFDLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBgdHVubmVsSW50ZXJjZXB0b3IoKWAgLSB0aGUge0BsaW5rIEludGVyY2VwdG9yfSB0aGF0IGZyb250cyBhbiBhcHAgd2l0aCBhIHB1YmxpY1xuICogcG9ydHIgYW5kL29yIGZycCB0dW5uZWwsIGNvbnN1bWluZyB0aGUge0BsaW5rIEludGVyY2VwdG9yQ29udGV4dH0gYEBkYngtdG9vbHMvYXBwa2l0YCdzXG4gKiBgY3JlYXRlQXBwYCBoYW5kcyBpdC5cbiAqXG4gKiBUaGUgdHVubmVsIHJ1bnMgSU4tUFJPQ0VTUzogdGhlIEFQUCBpcyB0aGUgbWFpbiBwcm9jZXNzIGFuZCBoYW5kcyB0aGlzIGludGVyY2VwdG9yXG4gKiBpdHMgY29udGV4dCwgcmF0aGVyIHRoYW4gYSB3cmFwcGVyIHByb2Nlc3Mgc3Bhd25pbmcgdGhlIGFwcCBhcyBhIGNoaWxkLiBUaGVcbiAqIGludGVyY2VwdG9yIGFwcGxpZXMgdGhlIGNvbXB1dGVkIHdvcmtzcGFjZSBob3N0LCBpbnN0YWxscyBhbmQgbGF1bmNoZXMgcG9ydHIgb24gdGhlXG4gKiBhcHAncyBwdWJsaWMgcG9ydCwgYmluZHMgdGhlIGNoaWxkIHByb2Nlc3MgdG8gdGhlIGFwcCwgYW5kIHN0b3BzIHBvcnRyIGR1cmluZyBhblxuICogb3JkZXJseSBBcHBLaXQgc2h1dGRvd24uXG4gKlxuICogVGhlIHBhc3N3b3JkbGVzcyBHQVRFIGlzIGEgc2VwYXJhdGUgY29uY2VybjogaXQgaXMgdGhlIGBhdXRoR2F0ZWAgQXBwS2l0IHBsdWdpbixcbiAqIHdoaWNoIHJlZ2lzdGVycyB0aGUgbG9naW4gcm91dGVzICsgYSBnYXRpbmcgbWlkZGxld2FyZSBvbiB0aGUgYXBwJ3Mgb3duIHNlcnZlci5cbiAqIFJlZ2lzdGVyIGl0IGluIHRoZSBhcHAncyBgcGx1Z2luc2AgZm9yIGdhdGVkIHRyYWZmaWMuIFRoaXMgaW50ZXJjZXB0b3IgaXMgb25seVxuICogdGhlIHBvcnRyIGhhbGYgLSBcInVwZGF0ZSB0aGUgaG9zdCwgYmluZCBwb3J0clwiIC0gdGhlIHNtYWxsZXN0IHVzZWZ1bCB1bml0LlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IEludGVyY2VwdG9yLCBJbnRlcmNlcHRvckNvbnRleHQgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXRcIjtcbmltcG9ydCB7IGxvZywgb2JqZWN0IH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7IGluc3RhbGxGcnAsIHJlc29sdmVGcnBDb25maWcsIHN1cGVydmlzZUZycCwgd3JpdGVGcnBDb25maWcgfSBmcm9tIFwiLi9mcnAudHNcIjtcbmltcG9ydCB7IGluc3RhbGxQb3J0ciwgcmVzb2x2ZVBvcnRyQ29uZmlnLCBzdXBlcnZpc2VQb3J0ciwgd3JpdGVQb3J0ckNvbmZpZyB9IGZyb20gXCIuL3BvcnRyLnRzXCI7XG5pbXBvcnQgeyBzdGFydFBhdGhQcm94eSB9IGZyb20gXCIuL3BhdGgtcHJveHkudHNcIjtcblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcInR1bm5lbDppbnRlcmNlcHRvclwiKTtcblxuLyoqIE9wdGlvbnMgZm9yIHtAbGluayB0dW5uZWxJbnRlcmNlcHRvcn0gKGVhY2ggYWxzbyByZXNvbHZhYmxlIGZyb20gZW52KS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVHVubmVsSW50ZXJjZXB0b3JPcHRpb25zIHtcbiAgLyoqIFR1bm5lbCBjbGllbnRzIHRvIHJ1bi4gRW52IGBEQlhfVE9PTFNfVFVOTkVMX1RSQU5TUE9SVGA7IGRlZmF1bHRzIHRvIGBwb3J0cmAuICovXG4gIHRyYW5zcG9ydD86IFR1bm5lbFRyYW5zcG9ydDtcbiAgLyoqIFB1YmxpYyBob3N0IHRvIHNlcnZlIG9uLiBFbnYgYFRVTk5FTF9QVUJMSUNfRE9NQUlOYC4gKi9cbiAgcHVibGljRG9tYWluPzogc3RyaW5nO1xuICAvKiogcG9ydHIgc3ViZG9tYWluIChlbHNlIGRlcml2ZWQgZnJvbSB7QGxpbmsgcHVibGljRG9tYWlufSkuICovXG4gIHN1YmRvbWFpbj86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBQVUJMSUMgcG9ydCBwb3J0ciBmb3J3YXJkcyB0byAtIHRoZSBwb3J0IHRoZSBhcHAgaXRzZWxmIGxpc3RlbnMgb24uXG4gICAqIERlZmF1bHRzIHRvIHRoZSBEYXRhYnJpY2tzIEFwcHMgcnVudGltZSBjb250cmFjdCBgREFUQUJSSUNLU19BUFBfUE9SVGBcbiAgICogKHRoZW4gYDgwMDBgKSwgd2hpY2ggaXMgdGhlIHBvcnQgdGhlIHBsYXRmb3JtIHJvdXRlcyB0by5cbiAgICovXG4gIHBvcnQ/OiBudW1iZXI7XG4gIC8qKiBmcnBzIGNvbnRyb2wgaG9zdDsgZGVmYXVsdHMgdG8gdGhlIEZSUCBwdWJsaWMgZG9tYWluLiBFbnYgYEZSUF9TRVJWRVJgLiAqL1xuICBmcnBTZXJ2ZXI/OiBzdHJpbmc7XG4gIC8qKiBGUlAgcHVibGljIEhUVFAgaG9zdC4gRW52IGBUVU5ORUxfRlJQX1BVQkxJQ19ET01BSU5gLiAqL1xuICBmcnBQdWJsaWNEb21haW4/OiBzdHJpbmc7XG4gIC8qKiBmcnBzIGNvbnRyb2wgcG9ydC4gRW52IGBGUlBfU0VSVkVSX1BPUlRgOyBkZWZhdWx0cyB0byBgNDQzYC4gKi9cbiAgZnJwU2VydmVyUG9ydD86IG51bWJlcjtcbiAgLyoqIGZycGMgdHJhbnNwb3J0IHByb3RvY29sLiBFbnYgYEZSUF9QUk9UT0NPTGA7IGRlZmF1bHRzIHRvIGB3c3NgLiAqL1xuICBmcnBQcm90b2NvbD86IHN0cmluZztcbiAgLyoqIGZycHMgYXV0aCB0b2tlbi4gRW52IGBGUlBfVE9LRU5gIChvciBgVFVOTkVMX1RPS0VOYCkuICovXG4gIGZycFRva2VuPzogc3RyaW5nO1xuICAvKiogZnJwIHByb3h5IHJlZ2lzdHJhdGlvbiBuYW1lLiBFbnYgYEZSUF9QUk9YWV9OQU1FYC4gKi9cbiAgZnJwUHJveHlOYW1lPzogc3RyaW5nO1xuICAvKiogRlJQIHBhdGggbG9jYXRpb24uIEVudiBgRlJQX1BBVEhgOyBkZWZhdWx0cyB0byBgREFUQUJSSUNLU19BUFBfTkFNRWAuICovXG4gIGZycFBhdGg/OiBzdHJpbmc7XG4gIC8qKiBTdHJpcCB0aGUgRlJQIHBhdGggYmVmb3JlIGZvcndhcmRpbmcuIEVudiBgRlJQX1NUUklQX1BSRUZJWGA7IGRlZmF1bHRzIHRydWUgZm9yIG5vbi1yb290IHBhdGhzLiAqL1xuICBmcnBTdHJpcFByZWZpeD86IGJvb2xlYW47XG59XG5cbi8qKiBQdWJsaWMgdHVubmVsIGNsaWVudHMgc3VwcG9ydGVkIGJ5IHRoZSBpbnRlcmNlcHRvciBhbmQgQ0xJLiAqL1xuZXhwb3J0IHR5cGUgVHVubmVsVHJhbnNwb3J0ID0gXCJwb3J0clwiIHwgXCJmcnBcIiB8IFwiYm90aFwiO1xuXG4vKiogUmVzb2x2ZSBhbmQgdmFsaWRhdGUgdGhlIHR1bm5lbCB0cmFuc3BvcnQgc2VsZWN0b3IuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZVR1bm5lbFRyYW5zcG9ydCh0cmFuc3BvcnQ/OiBzdHJpbmcpOiBUdW5uZWxUcmFuc3BvcnQge1xuICBjb25zdCByZXNvbHZlZCA9XG4gICAgdHJhbnNwb3J0ID8/XG4gICAgcHJvY2Vzcy5lbnYuREJYX1RPT0xTX1RVTk5FTF9UUkFOU1BPUlQgPz9cbiAgICBwcm9jZXNzLmVudi5UVU5ORUxfVFJBTlNQT1JUID8/XG4gICAgXCJwb3J0clwiO1xuICBpZiAocmVzb2x2ZWQgPT09IFwicG9ydHJcIiB8fCByZXNvbHZlZCA9PT0gXCJmcnBcIiB8fCByZXNvbHZlZCA9PT0gXCJib3RoXCIpIHJldHVybiByZXNvbHZlZDtcbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihgaW52YWxpZCB0dW5uZWwgdHJhbnNwb3J0OiAke3Jlc29sdmVkfSAoZXhwZWN0ZWQgcG9ydHIsIGZycCwgb3IgYm90aClgKTtcbn1cblxuLyoqIFJlc29sdmUgdGhlIHB1YmxpYyBwb3J0IHBvcnRyIHNob3VsZCB0YXJnZXQ6IGV4cGxpY2l0LCBlbHNlIHRoZSBBcHBzIGNvbnRyYWN0LiAqL1xuZnVuY3Rpb24gcmVzb2x2ZVB1YmxpY1BvcnQocG9ydD86IG51bWJlcik6IG51bWJlciB7XG4gIHJldHVybiBwb3J0ID8/IG9iamVjdC50b051bWJlcihwcm9jZXNzLmVudi5EQVRBQlJJQ0tTX0FQUF9QT1JUKSA/PyA4MDAwO1xufVxuXG4vKipcbiAqIEJ1aWxkIHRoZSB0dW5uZWwge0BsaW5rIEludGVyY2VwdG9yfS4gUGFzcyBpdCB0byBgY3JlYXRlQXBwKHsgaW50ZXJjZXB0b3IgfSlgLlxuICpcbiAqIEEgbm8tb3AgKGxvZ3MgYW5kIHJldHVybnMpIHdoZW4gbm9uZSBvZiB0aGUgc2VsZWN0ZWQgdHVubmVsIGNsaWVudHMgcmVzb2x2ZVxuICogdXNhYmxlIGNvbmZpZ3VyYXRpb24sIHNvIGFuIGFwcCBjYW4gcmVnaXN0ZXIgaXQgdW5jb25kaXRpb25hbGx5LlxuICpcbiAqIEBleGFtcGxlXG4gKiBpbXBvcnQgeyBhcHBraXQgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXRcIjtcbiAqIGltcG9ydCB7IHR1bm5lbEludGVyY2VwdG9yIH0gZnJvbSBcIkBkYngtdG9vbHMvdHVubmVsXCI7XG4gKlxuICogYXdhaXQgYXBwa2l0LmNyZWF0ZUFwcCh7XG4gKiAgIHBsdWdpbnM6IFtzZXJ2ZXIoeyBob3N0LCBzdGF0aWNQYXRoIH0pXSxcbiAqICAgaW50ZXJjZXB0b3I6IHR1bm5lbEludGVyY2VwdG9yKCksXG4gKiB9KTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHR1bm5lbEludGVyY2VwdG9yKG9wdGlvbnM6IFR1bm5lbEludGVyY2VwdG9yT3B0aW9ucyA9IHt9KTogSW50ZXJjZXB0b3Ige1xuICByZXR1cm4gYXN5bmMgKGN0eDogSW50ZXJjZXB0b3JDb250ZXh0KTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgaWYgKGN0eC5lbnYuZGF0YWJyaWNrc0hvc3QpIHtcbiAgICAgIHByb2Nlc3MuZW52LkRBVEFCUklDS1NfSE9TVCA/Pz0gY3R4LmVudi5kYXRhYnJpY2tzSG9zdDtcbiAgICB9XG5cbiAgICBjb25zdCBwb3J0ID0gcmVzb2x2ZVB1YmxpY1BvcnQob3B0aW9ucy5wb3J0KTtcbiAgICBjb25zdCB0cmFuc3BvcnQgPSByZXNvbHZlVHVubmVsVHJhbnNwb3J0KG9wdGlvbnMudHJhbnNwb3J0KTtcbiAgICBjb25zdCBhdXhpbGlhcmllczogQXJyYXk8eyBzdG9wKCk6IHZvaWQgfT4gPSBbXTtcbiAgICBpZiAodHJhbnNwb3J0ID09PSBcInBvcnRyXCIgfHwgdHJhbnNwb3J0ID09PSBcImJvdGhcIikge1xuICAgICAgY29uc3QgcG9ydHJDb25maWcgPSByZXNvbHZlUG9ydHJDb25maWcoe1xuICAgICAgICBwdWJsaWNEb21haW46IG9wdGlvbnMucHVibGljRG9tYWluLFxuICAgICAgICBzdWJkb21haW46IG9wdGlvbnMuc3ViZG9tYWluLFxuICAgICAgICBwb3J0LFxuICAgICAgfSk7XG4gICAgICBpZiAocG9ydHJDb25maWcpIHtcbiAgICAgICAgY29uc3QgcG9ydHJFbnYgPSBhd2FpdCBpbnN0YWxsUG9ydHIoKTtcbiAgICAgICAgYXdhaXQgd3JpdGVQb3J0ckNvbmZpZyhwb3J0ckNvbmZpZywgcG9ydHJFbnYpO1xuICAgICAgICBhdXhpbGlhcmllcy5wdXNoKHN1cGVydmlzZVBvcnRyKHBvcnRyQ29uZmlnLCBwb3J0ckVudikpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbG9nZ2VyLmluZm8oXCJwb3J0ciBub3QgY29uZmlndXJlZCAocmVxdWlyZXMgUE9SVFJfVE9LRU4gYW5kIFRVTk5FTF9QVUJMSUNfRE9NQUlOKVwiKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHRyYW5zcG9ydCA9PT0gXCJmcnBcIiB8fCB0cmFuc3BvcnQgPT09IFwiYm90aFwiKSB7XG4gICAgICBjb25zdCBmcnBDb25maWcgPSByZXNvbHZlRnJwQ29uZmlnKHtcbiAgICAgICAgcHVibGljRG9tYWluOiBvcHRpb25zLmZycFB1YmxpY0RvbWFpbixcbiAgICAgICAgc2VydmVyOiBvcHRpb25zLmZycFNlcnZlcixcbiAgICAgICAgc2VydmVyUG9ydDogb3B0aW9ucy5mcnBTZXJ2ZXJQb3J0LFxuICAgICAgICBwcm90b2NvbDogb3B0aW9ucy5mcnBQcm90b2NvbCxcbiAgICAgICAgdG9rZW46IG9wdGlvbnMuZnJwVG9rZW4sXG4gICAgICAgIHByb3h5TmFtZTogb3B0aW9ucy5mcnBQcm94eU5hbWUsXG4gICAgICAgIHBhdGg6IG9wdGlvbnMuZnJwUGF0aCxcbiAgICAgICAgc3RyaXBQcmVmaXg6IG9wdGlvbnMuZnJwU3RyaXBQcmVmaXgsXG4gICAgICAgIHBvcnQsXG4gICAgICB9KTtcbiAgICAgIGlmIChmcnBDb25maWcpIHtcbiAgICAgICAgY29uc3QgcGF0aFByb3h5ID1cbiAgICAgICAgICBmcnBDb25maWcuc3RyaXBQcmVmaXggJiYgZnJwQ29uZmlnLnBhdGggIT09IFwiL1wiXG4gICAgICAgICAgICA/IGF3YWl0IHN0YXJ0UGF0aFByb3h5KHBvcnQsIGZycENvbmZpZy5wYXRoKVxuICAgICAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChwYXRoUHJveHkpIHtcbiAgICAgICAgICBmcnBDb25maWcudGFyZ2V0UG9ydCA9IHBhdGhQcm94eS5wb3J0O1xuICAgICAgICAgIGN0eC5vbkxpZmVjeWNsZShcInNodXRkb3duXCIsICgpID0+IHZvaWQgcGF0aFByb3h5LmNsb3NlKCkpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGZycEVudiA9IGF3YWl0IGluc3RhbGxGcnAoKTtcbiAgICAgICAgY29uc3QgY29uZmlnUGF0aCA9IGF3YWl0IHdyaXRlRnJwQ29uZmlnKGZycENvbmZpZywgZnJwRW52KTtcbiAgICAgICAgYXV4aWxpYXJpZXMucHVzaChzdXBlcnZpc2VGcnAoZnJwQ29uZmlnLCBmcnBFbnYsIGNvbmZpZ1BhdGgpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxvZ2dlci5pbmZvKFwiZnJwIG5vdCBjb25maWd1cmVkIChyZXF1aXJlcyBUVU5ORUxfUFVCTElDX0RPTUFJTilcIik7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICghYXV4aWxpYXJpZXMubGVuZ3RoKSByZXR1cm47XG4gICAgY3R4Lm9uVGVhcmRvd24oKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCBhdXhpbGlhcnkgb2YgYXV4aWxpYXJpZXMpIGF1eGlsaWFyeS5zdG9wKCk7XG4gICAgfSk7XG4gICAgY3R4Lm9uTGlmZWN5Y2xlKFwic2h1dGRvd25cIiwgKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCBhdXhpbGlhcnkgb2YgYXV4aWxpYXJpZXMpIGF1eGlsaWFyeS5zdG9wKCk7XG4gICAgfSk7XG4gICAgbG9nZ2VyLmluZm8oYHR1bm5lbCBib3VuZDogJHt0cmFuc3BvcnR9IC0+IDoke3BvcnR9YCk7XG4gIH07XG59XG4iXX0=
143
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJjZXB0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW50ZXJjZXB0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBR0gsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsVUFBVSxFQUFFLGdCQUFnQixFQUFFLFlBQVksRUFBRSxjQUFjLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDdEYsT0FBTyxFQUFFLFlBQVksRUFBRSxrQkFBa0IsRUFBRSxjQUFjLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDaEcsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRWpELE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsb0JBQW9CLENBQUMsQ0FBQztBQWlEaEQsTUFBTSxjQUFjLEdBQWtCO0lBQ3BDLEtBQUssQ0FBQyxVQUFVLENBQUMsTUFBTTtRQUNyQixNQUFNLFFBQVEsR0FBRyxNQUFNLFlBQVksRUFBRSxDQUFDO1FBQ3RDLE1BQU0sZ0JBQWdCLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3pDLE9BQU8sY0FBYyxDQUFDLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBQ0QsS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsR0FBRztRQUN4QixNQUFNLFNBQVMsR0FDYixNQUFNLENBQUMsV0FBVyxJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssR0FBRztZQUN2QyxDQUFDLENBQUMsTUFBTSxjQUFjLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDO1lBQ3RELENBQUMsQ0FBQyxTQUFTLENBQUM7UUFDaEIsSUFBSSxTQUFTLEVBQUUsQ0FBQztZQUNkLE1BQU0sQ0FBQyxVQUFVLEdBQUcsU0FB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RSxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztvQkFDakUsU0FBUztnQkFDWCxDQUFDO2dCQUNELElBQUksT0FBTztvQkFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDOztvQkFDNUIsV0FBVyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDdEMsQ0FBQztZQUNELElBQUksQ0FBQyxPQUFPLElBQUksV0FBVyxDQUFDLE1BQU07Z0JBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsU0FBUyxRQUFRLElBQUksRUFBRSxDQUFDLENBQUM7UUFDNUYsQ0FBQyxDQUFDLENBQUM7UUFDSCxNQUFNLENBQUMsSUFBSSxDQUFDLG9DQUFvQyxTQUFTLFFBQVEsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUMzRSxDQUFDLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBgdHVubmVsSW50ZXJjZXB0b3IoKWAgLSB0aGUge0BsaW5rIEludGVyY2VwdG9yfSB0aGF0IGZyb250cyBhbiBhcHAgd2l0aCBhIHB1YmxpY1xuICogcG9ydHIgYW5kL29yIGZycCB0dW5uZWwsIGNvbnN1bWluZyB0aGUge0BsaW5rIEludGVyY2VwdG9yQ29udGV4dH0gYEBkYngtdG9vbHMvYXBwa2l0YCdzXG4gKiBgY3JlYXRlQXBwYCBoYW5kcyBpdC5cbiAqXG4gKiBUaGUgdHVubmVsIHJ1bnMgSU4tUFJPQ0VTUzogdGhlIEFQUCBpcyB0aGUgbWFpbiBwcm9jZXNzIGFuZCBoYW5kcyB0aGlzIGludGVyY2VwdG9yXG4gKiBpdHMgY29udGV4dCwgcmF0aGVyIHRoYW4gYSB3cmFwcGVyIHByb2Nlc3Mgc3Bhd25pbmcgdGhlIGFwcCBhcyBhIGNoaWxkLiBUaGVcbiAqIGludGVyY2VwdG9yIGFwcGxpZXMgdGhlIGNvbXB1dGVkIHdvcmtzcGFjZSBob3N0LCBpbnN0YWxscyBhbmQgbGF1bmNoZXMgcG9ydHIgb24gdGhlXG4gKiBhcHAncyBwdWJsaWMgcG9ydCwgYmluZHMgdGhlIGNoaWxkIHByb2Nlc3MgdG8gdGhlIGFwcCwgYW5kIHN0b3BzIHBvcnRyIGR1cmluZyBhblxuICogb3JkZXJseSBBcHBLaXQgc2h1dGRvd24uXG4gKlxuICogVGhlIHBhc3N3b3JkbGVzcyBHQVRFIGlzIGEgc2VwYXJhdGUgY29uY2VybjogaXQgaXMgdGhlIGBhdXRoR2F0ZWAgQXBwS2l0IHBsdWdpbixcbiAqIHdoaWNoIHJlZ2lzdGVycyB0aGUgbG9naW4gcm91dGVzICsgYSBnYXRpbmcgbWlkZGxld2FyZSBvbiB0aGUgYXBwJ3Mgb3duIHNlcnZlci5cbiAqIFJlZ2lzdGVyIGl0IGluIHRoZSBhcHAncyBgcGx1Z2luc2AgZm9yIGdhdGVkIHRyYWZmaWMuIFRoaXMgaW50ZXJjZXB0b3IgaXMgb25seVxuICogdGhlIHBvcnRyIGhhbGYgLSBcInVwZGF0ZSB0aGUgaG9zdCwgYmluZCBwb3J0clwiIC0gdGhlIHNtYWxsZXN0IHVzZWZ1bCB1bml0LlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IEludGVyY2VwdG9yLCBJbnRlcmNlcHRvckNvbnRleHQgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXRcIjtcbmltcG9ydCB7IGxvZywgb2JqZWN0IH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7IGluc3RhbGxGcnAsIHJlc29sdmVGcnBDb25maWcsIHN1cGVydmlzZUZycCwgd3JpdGVGcnBDb25maWcgfSBmcm9tIFwiLi9mcnAudHNcIjtcbmltcG9ydCB7IGluc3RhbGxQb3J0ciwgcmVzb2x2ZVBvcnRyQ29uZmlnLCBzdXBlcnZpc2VQb3J0ciwgd3JpdGVQb3J0ckNvbmZpZyB9IGZyb20gXCIuL3BvcnRyLnRzXCI7XG5pbXBvcnQgeyBzdGFydFBhdGhQcm94eSB9IGZyb20gXCIuL3BhdGgtcHJveHkudHNcIjtcblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcInR1bm5lbDppbnRlcmNlcHRvclwiKTtcblxuLyoqIE9wdGlvbnMgZm9yIHtAbGluayB0dW5uZWxJbnRlcmNlcHRvcn0gKGVhY2ggYWxzbyByZXNvbHZhYmxlIGZyb20gZW52KS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVHVubmVsSW50ZXJjZXB0b3JPcHRpb25zIHtcbiAgLyoqIFR1bm5lbCBjbGllbnRzIHRvIHJ1bi4gRW52IGBEQlhfVE9PTFNfVFVOTkVMX1RSQU5TUE9SVGA7IGRlZmF1bHRzIHRvIGBwb3J0cmAuICovXG4gIHRyYW5zcG9ydD86IFR1bm5lbFRyYW5zcG9ydDtcbiAgLyoqIFB1YmxpYyBob3N0IHRvIHNlcnZlIG9uLiBFbnYgYFRVTk5FTF9QVUJMSUNfRE9NQUlOYC4gKi9cbiAgcHVibGljRG9tYWluPzogc3RyaW5nO1xuICAvKiogcG9ydHIgc3ViZG9tYWluIChlbHNlIGRlcml2ZWQgZnJvbSB7QGxpbmsgcHVibGljRG9tYWlufSkuICovXG4gIHN1YmRvbWFpbj86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBQVUJMSUMgcG9ydCBwb3J0ciBmb3J3YXJkcyB0byAtIHRoZSBwb3J0IHRoZSBhcHAgaXRzZWxmIGxpc3RlbnMgb24uXG4gICAqIERlZmF1bHRzIHRvIHRoZSBEYXRhYnJpY2tzIEFwcHMgcnVudGltZSBjb250cmFjdCBgREFUQUJSSUNLU19BUFBfUE9SVGBcbiAgICogKHRoZW4gYDgwMDBgKSwgd2hpY2ggaXMgdGhlIHBvcnQgdGhlIHBsYXRmb3JtIHJvdXRlcyB0by5cbiAgICovXG4gIHBvcnQ/OiBudW1iZXI7XG4gIC8qKiBmcnBzIGNvbnRyb2wgaG9zdDsgZGVmYXVsdHMgdG8gdGhlIEZSUCBwdWJsaWMgZG9tYWluLiBFbnYgYEZSUF9TRVJWRVJgLiAqL1xuICBmcnBTZXJ2ZXI/OiBzdHJpbmc7XG4gIC8qKiBGUlAgcHVibGljIEhUVFAgaG9zdC4gRW52IGBUVU5ORUxfRlJQX1BVQkxJQ19ET01BSU5gLiAqL1xuICBmcnBQdWJsaWNEb21haW4/OiBzdHJpbmc7XG4gIC8qKiBmcnBzIGNvbnRyb2wgcG9ydC4gRW52IGBGUlBfU0VSVkVSX1BPUlRgOyBkZWZhdWx0cyB0byBgNDQzYC4gKi9cbiAgZnJwU2VydmVyUG9ydD86IG51bWJlcjtcbiAgLyoqIGZycGMgdHJhbnNwb3J0IHByb3RvY29sLiBFbnYgYEZSUF9QUk9UT0NPTGA7IGRlZmF1bHRzIHRvIGB3c3NgLiAqL1xuICBmcnBQcm90b2NvbD86IHN0cmluZztcbiAgLyoqIGZycHMgYXV0aCB0b2tlbi4gRW52IGBGUlBfVE9LRU5gIChvciBgVFVOTkVMX1RPS0VOYCkuICovXG4gIGZycFRva2VuPzogc3RyaW5nO1xuICAvKiogZnJwIHByb3h5IHJlZ2lzdHJhdGlvbiBuYW1lLiBFbnYgYEZSUF9QUk9YWV9OQU1FYC4gKi9cbiAgZnJwUHJveHlOYW1lPzogc3RyaW5nO1xuICAvKiogRlJQIHBhdGggbG9jYXRpb24uIEVudiBgRlJQX1BBVEhgOyBkZWZhdWx0cyB0byBgREFUQUJSSUNLU19BUFBfTkFNRWAuICovXG4gIGZycFBhdGg/OiBzdHJpbmc7XG4gIC8qKiBTdHJpcCB0aGUgRlJQIHBhdGggYmVmb3JlIGZvcndhcmRpbmcuIEVudiBgRlJQX1NUUklQX1BSRUZJWGA7IGRlZmF1bHRzIHRydWUgZm9yIG5vbi1yb290IHBhdGhzLiAqL1xuICBmcnBTdHJpcFByZWZpeD86IGJvb2xlYW47XG59XG5cbi8qKiBQdWJsaWMgdHVubmVsIGNsaWVudHMgc3VwcG9ydGVkIGJ5IHRoZSBpbnRlcmNlcHRvciBhbmQgQ0xJLiAqL1xuZXhwb3J0IHR5cGUgVHVubmVsVHJhbnNwb3J0ID0gXCJwb3J0clwiIHwgXCJmcnBcIiB8IFwiYm90aFwiO1xuXG5pbnRlcmZhY2UgVHVubmVsQXV4aWxpYXJ5IHtcbiAgc3RvcCgpOiB2b2lkO1xufVxuXG5pbnRlcmZhY2UgVHVubmVsUnVudGltZSB7XG4gIHN0YXJ0UG9ydHIoY29uZmlnOiBOb25OdWxsYWJsZTxSZXR1cm5UeXBlPHR5cGVvZiByZXNvbHZlUG9ydHJDb25maWc+Pik6IFByb21pc2U8VHVubmVsQXV4aWxpYXJ5PjtcbiAgc3RhcnRGcnAoXG4gICAgY29uZmlnOiBOb25OdWxsYWJsZTxSZXR1cm5UeXBlPHR5cGVvZiByZXNvbHZlRnJwQ29uZmlnPj4sXG4gICAgY3R4OiBJbnRlcmNlcHRvckNvbnRleHQsXG4gICk6IFByb21pc2U8VHVubmVsQXV4aWxpYXJ5Pjtcbn1cblxuY29uc3QgZGVmYXVsdFJ1bnRpbWU6IFR1bm5lbFJ1bnRpbWUgPSB7XG4gIGFzeW5jIHN0YXJ0UG9ydHIoY29uZmlnKSB7XG4gICAgY29uc3QgcG9ydHJFbnYgPSBhd2FpdCBpbnN0YWxsUG9ydHIoKTtcbiAgICBhd2FpdCB3cml0ZVBvcnRyQ29uZmlnKGNvbmZpZywgcG9ydHJFbnYpO1xuICAgIHJldHVybiBzdXBlcnZpc2VQb3J0cihjb25maWcsIHBvcnRyRW52KTtcbiAgfSxcbiAgYXN5bmMgc3RhcnRGcnAoY29uZmlnLCBjdHgpIHtcbiAgICBjb25zdCBwYXRoUHJveHkgPVxuICAgICAgY29uZmlnLnN0cmlwUHJlZml4ICYmIGNvbmZpZy5wYXRoICE9PSBcIi9cIlxuICAgICAgICA/IGF3YWl0IHN0YXJ0UGF0aFByb3h5KGNvbmZpZy50YXJnZXRQb3J0LCBjb25maWcucGF0aClcbiAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgaWYgKHBhdGhQcm94eSkge1xuICAgICAgY29uZmlnLnRhcmdldFBvcnQgPSBwYXRoUHJveHkucG9ydDtcbiAgICAgIGN0eC5vbkxpZmVjeWNsZShcInNodXRkb3duXCIsICgpID0+IHZvaWQgcGF0aFByb3h5LmNsb3NlKCkpO1xuICAgIH1cbiAgICBjb25zdCBmcnBFbnYgPSBhd2FpdCBpbnN0YWxsRnJwKCk7XG4gICAgY29uc3QgY29uZmlnUGF0aCA9IGF3YWl0IHdyaXRlRnJwQ29uZmlnKGNvbmZpZywgZnJwRW52KTtcbiAgICBjb25zdCBzdXBlcnZpc29yID0gc3VwZXJ2aXNlRnJwKGNvbmZpZywgZnJwRW52LCBjb25maWdQYXRoKTtcbiAgICByZXR1cm4ge1xuICAgICAgc3RvcCgpIHtcbiAgICAgICAgc3VwZXJ2aXNvci5zdG9wKCk7XG4gICAgICAgIHZvaWQgcGF0aFByb3h5Py5jbG9zZSgpO1xuICAgICAgfSxcbiAgICB9O1xuICB9LFxufTtcblxuLyoqIFJlc29sdmUgYW5kIHZhbGlkYXRlIHRoZSB0dW5uZWwgdHJhbnNwb3J0IHNlbGVjdG9yLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVUdW5uZWxUcmFuc3BvcnQodHJhbnNwb3J0Pzogc3RyaW5nKTogVHVubmVsVHJhbnNwb3J0IHtcbiAgY29uc3QgcmVzb2x2ZWQgPVxuICAgIHRyYW5zcG9ydCA/PyBwcm9jZXNzLmVudi5EQlhfVE9PTFNfVFVOTkVMX1RSQU5TUE9SVCA/PyBwcm9jZXNzLmVudi5UVU5ORUxfVFJBTlNQT1JUID8/IFwicG9ydHJcIjtcbiAgaWYgKHJlc29sdmVkID09PSBcInBvcnRyXCIgfHwgcmVzb2x2ZWQgPT09IFwiZnJwXCIgfHwgcmVzb2x2ZWQgPT09IFwiYm90aFwiKSByZXR1cm4gcmVzb2x2ZWQ7XG4gIHRocm93IG5ldyBUeXBlRXJyb3IoYGludmFsaWQgdHVubmVsIHRyYW5zcG9ydDogJHtyZXNvbHZlZH0gKGV4cGVjdGVkIHBvcnRyLCBmcnAsIG9yIGJvdGgpYCk7XG59XG5cbi8qKiBSZXNvbHZlIHRoZSBwdWJsaWMgcG9ydCBwb3J0ciBzaG91bGQgdGFyZ2V0OiBleHBsaWNpdCwgZWxzZSB0aGUgQXBwcyBjb250cmFjdC4gKi9cbmZ1bmN0aW9uIHJlc29sdmVQdWJsaWNQb3J0KHBvcnQ/OiBudW1iZXIpOiBudW1iZXIge1xuICByZXR1cm4gcG9ydCA/PyBvYmplY3QudG9OdW1iZXIocHJvY2Vzcy5lbnYuREFUQUJSSUNLU19BUFBfUE9SVCkgPz8gODAwMDtcbn1cblxuLyoqXG4gKiBCdWlsZCB0aGUgdHVubmVsIHtAbGluayBJbnRlcmNlcHRvcn0uIFBhc3MgaXQgdG8gYGNyZWF0ZUFwcCh7IGludGVyY2VwdG9yIH0pYC5cbiAqXG4gKiBBIG5vLW9wIChsb2dzIGFuZCByZXR1cm5zKSB3aGVuIG5vbmUgb2YgdGhlIHNlbGVjdGVkIHR1bm5lbCBjbGllbnRzIHJlc29sdmVcbiAqIHVzYWJsZSBjb25maWd1cmF0aW9uLCBzbyBhbiBhcHAgY2FuIHJlZ2lzdGVyIGl0IHVuY29uZGl0aW9uYWxseS5cbiAqXG4gKiBAZXhhbXBsZVxuICogaW1wb3J0IHsgYXBwa2l0IH0gZnJvbSBcIkBkYngtdG9vbHMvYXBwa2l0XCI7XG4gKiBpbXBvcnQgeyB0dW5uZWxJbnRlcmNlcHRvciB9IGZyb20gXCJAZGJ4LXRvb2xzL3R1bm5lbFwiO1xuICpcbiAqIGF3YWl0IGFwcGtpdC5jcmVhdGVBcHAoe1xuICogICBwbHVnaW5zOiBbc2VydmVyKHsgaG9zdCwgc3RhdGljUGF0aCB9KV0sXG4gKiAgIGludGVyY2VwdG9yOiB0dW5uZWxJbnRlcmNlcHRvcigpLFxuICogfSk7XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0dW5uZWxJbnRlcmNlcHRvcihcbiAgb3B0aW9uczogVHVubmVsSW50ZXJjZXB0b3JPcHRpb25zID0ge30sXG4gIHJ1bnRpbWU6IFR1bm5lbFJ1bnRpbWUgPSBkZWZhdWx0UnVudGltZSxcbik6IEludGVyY2VwdG9yIHtcbiAgcmV0dXJuIGFzeW5jIChjdHg6IEludGVyY2VwdG9yQ29udGV4dCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGlmIChjdHguZW52LmRhdGFicmlja3NIb3N0KSB7XG4gICAgICBwcm9jZXNzLmVudi5EQVRBQlJJQ0tTX0hPU1QgPz89IGN0eC5lbnYuZGF0YWJyaWNrc0hvc3Q7XG4gICAgfVxuXG4gICAgY29uc3QgcG9ydCA9IHJlc29sdmVQdWJsaWNQb3J0KG9wdGlvbnMucG9ydCk7XG4gICAgY29uc3QgdHJhbnNwb3J0ID0gcmVzb2x2ZVR1bm5lbFRyYW5zcG9ydChvcHRpb25zLnRyYW5zcG9ydCk7XG4gICAgY29uc3QgaW5pdGlhbGl6ZXJzOiBBcnJheTxQcm9taXNlPFR1bm5lbEF1eGlsaWFyeT4+ID0gW107XG4gICAgaWYgKHRyYW5zcG9ydCA9PT0gXCJwb3J0clwiIHx8IHRyYW5zcG9ydCA9PT0gXCJib3RoXCIpIHtcbiAgICAgIGNvbnN0IHBvcnRyQ29uZmlnID0gcmVzb2x2ZVBvcnRyQ29uZmlnKHtcbiAgICAgICAgcHVibGljRG9tYWluOiBvcHRpb25zLnB1YmxpY0RvbWFpbixcbiAgICAgICAgc3ViZG9tYWluOiBvcHRpb25zLnN1YmRvbWFpbixcbiAgICAgICAgcG9ydCxcbiAgICAgIH0pO1xuICAgICAgaWYgKHBvcnRyQ29uZmlnKSB7XG4gICAgICAgIGluaXRpYWxpemVycy5wdXNoKHJ1bnRpbWUuc3RhcnRQb3J0cihwb3J0ckNvbmZpZykpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbG9nZ2VyLmluZm8oXCJwb3J0ciBub3QgY29uZmlndXJlZCAocmVxdWlyZXMgUE9SVFJfVE9LRU4gYW5kIFRVTk5FTF9QVUJMSUNfRE9NQUlOKVwiKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHRyYW5zcG9ydCA9PT0gXCJmcnBcIiB8fCB0cmFuc3BvcnQgPT09IFwiYm90aFwiKSB7XG4gICAgICBjb25zdCBmcnBDb25maWcgPSByZXNvbHZlRnJwQ29uZmlnKHtcbiAgICAgICAgcHVibGljRG9tYWluOiBvcHRpb25zLmZycFB1YmxpY0RvbWFpbixcbiAgICAgICAgc2VydmVyOiBvcHRpb25zLmZycFNlcnZlcixcbiAgICAgICAgc2VydmVyUG9ydDogb3B0aW9ucy5mcnBTZXJ2ZXJQb3J0LFxuICAgICAgICBwcm90b2NvbDogb3B0aW9ucy5mcnBQcm90b2NvbCxcbiAgICAgICAgdG9rZW46IG9wdGlvbnMuZnJwVG9rZW4sXG4gICAgICAgIHByb3h5TmFtZTogb3B0aW9ucy5mcnBQcm94eU5hbWUsXG4gICAgICAgIHBhdGg6IG9wdGlvbnMuZnJwUGF0aCxcbiAgICAgICAgc3RyaXBQcmVmaXg6IG9wdGlvbnMuZnJwU3RyaXBQcmVmaXgsXG4gICAgICAgIHBvcnQsXG4gICAgICB9KTtcbiAgICAgIGlmIChmcnBDb25maWcpIHtcbiAgICAgICAgaW5pdGlhbGl6ZXJzLnB1c2gocnVudGltZS5zdGFydEZycChmcnBDb25maWcsIGN0eCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbG9nZ2VyLmluZm8oXCJmcnAgbm90IGNvbmZpZ3VyZWQgKHJlcXVpcmVzIFRVTk5FTF9QVUJMSUNfRE9NQUlOKVwiKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFpbml0aWFsaXplcnMubGVuZ3RoKSByZXR1cm47XG4gICAgY29uc3QgYXV4aWxpYXJpZXM6IFR1bm5lbEF1eGlsaWFyeVtdID0gW107XG4gICAgbGV0IHN0b3BwZWQgPSBmYWxzZTtcbiAgICBjb25zdCBzdG9wID0gKCkgPT4ge1xuICAgICAgc3RvcHBlZCA9IHRydWU7XG4gICAgICBmb3IgKGNvbnN0IGF1eGlsaWFyeSBvZiBhdXhpbGlhcmllcykgYXV4aWxpYXJ5LnN0b3AoKTtcbiAgICB9O1xuICAgIGN0eC5vblRlYXJkb3duKHN0b3ApO1xuICAgIGN0eC5vbkxpZmVjeWNsZShcInNodXRkb3duXCIsIHN0b3ApO1xuICAgIHZvaWQgUHJvbWlzZS5hbGxTZXR0bGVkKGluaXRpYWxpemVycykudGhlbigocmVzdWx0cykgPT4ge1xuICAgICAgZm9yIChjb25zdCByZXN1bHQgb2YgcmVzdWx0cykge1xuICAgICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gXCJyZWplY3RlZFwiKSB7XG4gICAgICAgICAgbG9nZ2VyLmVycm9yKFwidHVubmVsIGZhaWxlZCB0byBzdGFydFwiLCB7IGVycm9yOiByZXN1bHQucmVhc29uIH0pO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChzdG9wcGVkKSByZXN1bHQudmFsdWUuc3RvcCgpO1xuICAgICAgICBlbHNlIGF1eGlsaWFyaWVzLnB1c2gocmVzdWx0LnZhbHVlKTtcbiAgICAgIH1cbiAgICAgIGlmICghc3RvcHBlZCAmJiBhdXhpbGlhcmllcy5sZW5ndGgpIGxvZ2dlci5pbmZvKGB0dW5uZWwgYm91bmQ6ICR7dHJhbnNwb3J0fSAtPiA6JHtwb3J0fWApO1xuICAgIH0pO1xuICAgIGxvZ2dlci5pbmZvKGB0dW5uZWwgaW5pdGlhbGl6YXRpb24gc2NoZWR1bGVkOiAke3RyYW5zcG9ydH0gLT4gOiR7cG9ydH1gKTtcbiAgfTtcbn1cbiJdfQ==
@@ -8,4 +8,5 @@ export declare function superviseProcessForever(options: {
8
8
  logger: Logger;
9
9
  start: () => ChildProcess | Promise<ChildProcess>;
10
10
  retryDelaysMs?: readonly number[];
11
+ shutdownGraceMs?: number;
11
12
  }): ProcessSupervisor;
@@ -1,18 +1,25 @@
1
1
  import { async as asyncTools } from "@dbx-tools/shared-core";
2
2
  const STABLE_CONNECTION_MS = 60_000;
3
+ const DEFAULT_SHUTDOWN_GRACE_MS = 10_000;
3
4
  export function superviseProcessForever(options) {
4
5
  const controller = new AbortController();
5
6
  let child;
7
+ const terminateChild = () => {
8
+ const stoppingChild = child;
9
+ if (!stoppingChild)
10
+ return;
11
+ stoppingChild.kill("SIGTERM");
12
+ setTimeout(() => stoppingChild.kill("SIGKILL"), options.shutdownGraceMs ?? DEFAULT_SHUTDOWN_GRACE_MS).unref();
13
+ };
6
14
  const stop = () => {
7
15
  if (controller.signal.aborted)
8
16
  return;
9
17
  controller.abort();
10
- if (child && !child.killed)
11
- child.kill("SIGTERM");
18
+ terminateChild();
12
19
  process.off("exit", onProcessExit);
13
20
  };
14
21
  const onProcessExit = () => {
15
- if (child && !child.killed)
22
+ if (child)
16
23
  child.kill("SIGTERM");
17
24
  };
18
25
  process.once("exit", onProcessExit);
@@ -60,13 +67,10 @@ function processOutcome(child, signal) {
60
67
  };
61
68
  const onExit = (code, exitSignal) => finish({ code, signal: exitSignal });
62
69
  const onError = (error) => {
63
- if (!child.killed)
64
- child.kill("SIGTERM");
70
+ child.kill("SIGTERM");
65
71
  finish({ error });
66
72
  };
67
73
  const onAbort = () => {
68
- if (!child.killed)
69
- child.kill("SIGTERM");
70
74
  finish({ signal: "SIGTERM" });
71
75
  };
72
76
  child.once("exit", onExit);
@@ -74,4 +78,4 @@ function processOutcome(child, signal) {
74
78
  signal.addEventListener("abort", onAbort, { once: true });
75
79
  });
76
80
  }
77
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3VwZXJ2aXNvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdXBlcnZpc29yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxLQUFLLElBQUksVUFBVSxFQUFlLE1BQU0sd0JBQXdCLENBQUM7QUFFMUUsTUFBTSxvQkFBb0IsR0FBRyxNQUFNLENBQUM7QUFZcEMsTUFBTSxVQUFVLHVCQUF1QixDQUFDLE9BS3ZDO0lBQ0MsTUFBTSxVQUFVLEdBQUcsSUFBSSxlQUFlLEVBQUUsQ0FBQztJQUN6QyxJQUFJLEtBQStCLENBQUM7SUFFcEMsTUFBTSxJQUFJLEdBQUcsR0FBRyxFQUFFO1FBQ2hCLElBQUksVUFBVSxDQUFDLE1BQU0sQ0FBQyxPQUFPO1lBQUUsT0FBTztRQUN0QyxVQUFVLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDbkIsSUFBSSxLQUFLLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTTtZQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDbEQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsYUFBYSxDQUFDLENBQUM7SUFDckMsQ0FBQyxDQUFDO0lBQ0YsTUFBTSxhQUFhLEdBQUcsR0FBRyxFQUFFO1FBQ3pCLElBQUksS0FBSyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU07WUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3BELENBQUMsQ0FBQztJQUNGLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBRXBDLE1BQU0sR0FBRyxHQUFHLEtBQUssSUFBSSxFQUFFO1FBQ3JCLElBQUksUUFBUSxHQUFHLENBQUMsQ0FBQztRQUNqQixPQUFPLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNsQyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDN0IsSUFB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LE9BQU8sQ0FBQyxDQUFDO1FBQzdCLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDNUQsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBDaGlsZFByb2Nlc3MgfSBmcm9tIFwibm9kZTpjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgeyBhc3luYyBhcyBhc3luY1Rvb2xzLCB0eXBlIExvZ2dlciB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5cbmNvbnN0IFNUQUJMRV9DT05ORUNUSU9OX01TID0gNjBfMDAwO1xuXG5leHBvcnQgaW50ZXJmYWNlIFByb2Nlc3NTdXBlcnZpc29yIHtcbiAgc3RvcCgpOiB2b2lkO1xufVxuXG50eXBlIFByb2Nlc3NPdXRjb21lID0ge1xuICBjb2RlPzogbnVtYmVyIHwgbnVsbDtcbiAgc2lnbmFsPzogTm9kZUpTLlNpZ25hbHMgfCBudWxsO1xuICBlcnJvcj86IHVua25vd247XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gc3VwZXJ2aXNlUHJvY2Vzc0ZvcmV2ZXIob3B0aW9uczoge1xuICBuYW1lOiBzdHJpbmc7XG4gIGxvZ2dlcjogTG9nZ2VyO1xuICBzdGFydDogKCkgPT4gQ2hpbGRQcm9jZXNzIHwgUHJvbWlzZTxDaGlsZFByb2Nlc3M+O1xuICByZXRyeURlbGF5c01zPzogcmVhZG9ubHkgbnVtYmVyW107XG59KTogUHJvY2Vzc1N1cGVydmlzb3Ige1xuICBjb25zdCBjb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuICBsZXQgY2hpbGQ6IENoaWxkUHJvY2VzcyB8IHVuZGVmaW5lZDtcblxuICBjb25zdCBzdG9wID0gKCkgPT4ge1xuICAgIGlmIChjb250cm9sbGVyLnNpZ25hbC5hYm9ydGVkKSByZXR1cm47XG4gICAgY29udHJvbGxlci5hYm9ydCgpO1xuICAgIGlmIChjaGlsZCAmJiAhY2hpbGQua2lsbGVkKSBjaGlsZC5raWxsKFwiU0lHVEVSTVwiKTtcbiAgICBwcm9jZXNzLm9mZihcImV4aXRcIiwgb25Qcm9jZXNzRXhpdCk7XG4gIH07XG4gIGNvbnN0IG9uUHJvY2Vzc0V4aXQgPSAoKSA9PiB7XG4gICAgaWYgKGNoaWxkICYmICFjaGlsZC5raWxsZWQpIGNoaWxkLmtpbGwoXCJTSUdURVJNXCIpO1xuICB9O1xuICBwcm9jZXNzLm9uY2UoXCJleGl0XCIsIG9uUHJvY2Vzc0V4aXQpO1xuXG4gIGNvbnN0IHJ1biA9IGFzeW5jICgpID0+IHtcbiAgICBsZXQgZmFpbHVyZXMgPSAwO1xuICAgIHdoaWxlICghY29udHJvbGxlci5zaWduYWwuYWJvcnRlZCkge1xuICAgICAgY29uc3Qgc3RhcnRlZEF0ID0gRGF0ZS5ub3coKTtcbiAgICAgIGxldCBvdXRjb21lOiBQcm9jZXNzT3V0Y29tZTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNoaWxkID0gYXdhaXQgb3B0aW9ucy5zdGFydCgpO1xuICAgICAgICBvdXRjb21lID0gYXdhaXQgcHJvY2Vzc091dGNvbWUoY2hpbGQsIGNvbnRyb2xsZXIuc2lnbmFsKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIG91dGNvbWUgPSB7IGVycm9yIH07XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBjaGlsZCA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGlmIChjb250cm9sbGVyLnNpZ25hbC5hYm9ydGVkKSByZXR1cm47XG4gICAgICBpZiAoRGF0ZS5ub3coKSAtIHN0YXJ0ZWRBdCA+PSBTVEFCTEVfQ09OTkVDVElPTl9NUykgZmFpbHVyZXMgPSAwO1xuICAgICAgY29uc3QgZGVsYXlNcyA9IGFzeW5jVG9vbHMuYm91bmRlZFJldHJ5RGVsYXkoZmFpbHVyZXMrKywgb3B0aW9ucy5yZXRyeURlbGF5c01zKTtcbiAgICAgIG9wdGlvbnMubG9nZ2VyLndhcm4oYCR7b3B0aW9ucy5uYW1lfSBzdG9wcGVkOyByZXRyeWluZ2AsIHsgLi4ub3V0Y29tZSwgZGVsYXlNcyB9KTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGFzeW5jVG9vbHMuc2xlZXAoZGVsYXlNcywgY29udHJvbGxlci5zaWduYWwpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgdm9pZCBydW4oKS5jYXRjaCgoZXJyb3IpID0+IG9wdGlvbnMubG9nZ2VyLmVycm9yKGAke29wdGlvbnMubmFtZX0gc3VwZXJ2aXNvciBmYWlsZWRgLCB7IGVycm9yIH0pKTtcbiAgcmV0dXJuIHtcbiAgICBzdG9wLFxuICB9O1xufVxuXG5mdW5jdGlvbiBwcm9jZXNzT3V0Y29tZShjaGlsZDogQ2hpbGRQcm9jZXNzLCBzaWduYWw6IEFib3J0U2lnbmFsKTogUHJvbWlzZTxQcm9jZXNzT3V0Y29tZT4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICBjb25zdCBmaW5pc2ggPSAob3V0Y29tZTogUHJvY2Vzc091dGNvbWUpID0+IHtcbiAgICAgIGNoaWxkLm9mZihcImV4aXRcIiwgb25FeGl0KTtcbiAgICAgIGNoaWxkLm9mZihcImVycm9yXCIsIG9uRXJyb3IpO1xuICAgICAgc2lnbmFsLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJhYm9ydFwiLCBvbkFib3J0KTtcbiAgICAgIHJlc29sdmUob3V0Y29tZSk7XG4gICAgfTtcbiAgICBjb25zdCBvbkV4aXQgPSAoY29kZTogbnVtYmVyIHwgbnVsbCwgZXhpdFNpZ25hbDogTm9kZUpTLlNpZ25hbHMgfCBudWxsKSA9PlxuICAgICAgZmluaXNoKHsgY29kZSwgc2lnbmFsOiBleGl0U2lnbmFsIH0pO1xuICAgIGNvbnN0IG9uRXJyb3IgPSAoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICBpZiAoIWNoaWxkLmtpbGxlZCkgY2hpbGQua2lsbChcIlNJR1RFUk1cIik7XG4gICAgICBmaW5pc2goeyBlcnJvciB9KTtcbiAgICB9O1xuICAgIGNvbnN0IG9uQWJvcnQgPSAoKSA9PiB7XG4gICAgICBpZiAoIWNoaWxkLmtpbGxlZCkgY2hpbGQua2lsbChcIlNJR1RFUk1cIik7XG4gICAgICBmaW5pc2goeyBzaWduYWw6IFwiU0lHVEVSTVwiIH0pO1xuICAgIH07XG4gICAgY2hpbGQub25jZShcImV4aXRcIiwgb25FeGl0KTtcbiAgICBjaGlsZC5vbmNlKFwiZXJyb3JcIiwgb25FcnJvcik7XG4gICAgc2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIoXCJhYm9ydFwiLCBvbkFib3J0LCB7IG9uY2U6IHRydWUgfSk7XG4gIH0pO1xufVxuIl19
81
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3VwZXJ2aXNvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zdXBlcnZpc29yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxLQUFLLElBQUksVUFBVSxFQUFlLE1BQU0sd0JBQXdCLENBQUM7QUFFMUUsTUFBTSxvQkFBb0IsR0FBRyxNQUFNLENBQUM7QUFDcEMsTUFBTSx5QkFBeUIsR0FBRyxNQUFNLENBQUM7QUFZekMsTUFBTSxVQUFVLHVCQUF1QixDQUFDLE9BTXZDO0lBQ0MsTUFBTSxVQUFVLEdBQUcsSUFBSSxlQUFlLEVBQUUsQ0FBQztJQUN6QyxJQUFJLEtBQStCLENBQUM7SUFFcEMsTUFBTSxjQUFjLEdBQUcsR0FBRyxFQUFFO1FBQzFCLE1BQU0sYUFBYSxHQUFHLEtBQUssQ0FBQztRQUM1QixJQUFJLENBQUMsYUFBYTtZQUFFLE9BQU87UUFDM0IsYUFBYSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUM5QixVQUFVLENBQ1IsR0FBRyxFQUFFLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFDbkMsT0FBTyxDQUFDLGVBQWUsSUFBSSx5QkFBeUIsQ0FDckQsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNaLENBQUMsQ0FBQztJQUVGLE1BQU0sSUFBSSxHQUFHLEdBQUcsRUFBRTtRQUNoQixJQUFJLFVBQVUsQ0FBQyxNQUFNLENBQUMsT0FBTztZQUFFLE9BQU87UUFDdEMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ25CLGNBQWMsRUFBRSxDQUFDO1FBQ2pCLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBQ3JDLENBQUMsQ0FBQztJQUNGLE1BQU0sYUFBYSxHQUFHLEdBQUcsRUFBRTtRQUN6QixJQUFJLEtBQUs7WUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ25DLENBQUMsQ0FBQztJQUNGLE9B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RSxDQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDO1FBQ0YsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDM0IsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDN0IsTUFBTSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUM1RCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7IENoaWxkUHJvY2VzcyB9IGZyb20gXCJub2RlOmNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCB7IGFzeW5jIGFzIGFzeW5jVG9vbHMsIHR5cGUgTG9nZ2VyIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcblxuY29uc3QgU1RBQkxFX0NPTk5FQ1RJT05fTVMgPSA2MF8wMDA7XG5jb25zdCBERUZBVUxUX1NIVVRET1dOX0dSQUNFX01TID0gMTBfMDAwO1xuXG5leHBvcnQgaW50ZXJmYWNlIFByb2Nlc3NTdXBlcnZpc29yIHtcbiAgc3RvcCgpOiB2b2lkO1xufVxuXG50eXBlIFByb2Nlc3NPdXRjb21lID0ge1xuICBjb2RlPzogbnVtYmVyIHwgbnVsbDtcbiAgc2lnbmFsPzogTm9kZUpTLlNpZ25hbHMgfCBudWxsO1xuICBlcnJvcj86IHVua25vd247XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gc3VwZXJ2aXNlUHJvY2Vzc0ZvcmV2ZXIob3B0aW9uczoge1xuICBuYW1lOiBzdHJpbmc7XG4gIGxvZ2dlcjogTG9nZ2VyO1xuICBzdGFydDogKCkgPT4gQ2hpbGRQcm9jZXNzIHwgUHJvbWlzZTxDaGlsZFByb2Nlc3M+O1xuICByZXRyeURlbGF5c01zPzogcmVhZG9ubHkgbnVtYmVyW107XG4gIHNodXRkb3duR3JhY2VNcz86IG51bWJlcjtcbn0pOiBQcm9jZXNzU3VwZXJ2aXNvciB7XG4gIGNvbnN0IGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gIGxldCBjaGlsZDogQ2hpbGRQcm9jZXNzIHwgdW5kZWZpbmVkO1xuXG4gIGNvbnN0IHRlcm1pbmF0ZUNoaWxkID0gKCkgPT4ge1xuICAgIGNvbnN0IHN0b3BwaW5nQ2hpbGQgPSBjaGlsZDtcbiAgICBpZiAoIXN0b3BwaW5nQ2hpbGQpIHJldHVybjtcbiAgICBzdG9wcGluZ0NoaWxkLmtpbGwoXCJTSUdURVJNXCIpO1xuICAgIHNldFRpbWVvdXQoXG4gICAgICAoKSA9PiBzdG9wcGluZ0NoaWxkLmtpbGwoXCJTSUdLSUxMXCIpLFxuICAgICAgb3B0aW9ucy5zaHV0ZG93bkdyYWNlTXMgPz8gREVGQVVMVF9TSFVURE9XTl9HUkFDRV9NUyxcbiAgICApLnVucmVmKCk7XG4gIH07XG5cbiAgY29uc3Qgc3RvcCA9ICgpID0+IHtcbiAgICBpZiAoY29udHJvbGxlci5zaWduYWwuYWJvcnRlZCkgcmV0dXJuO1xuICAgIGNvbnRyb2xsZXIuYWJvcnQoKTtcbiAgICB0ZXJtaW5hdGVDaGlsZCgpO1xuICAgIHByb2Nlc3Mub2ZmKFwiZXhpdFwiLCBvblByb2Nlc3NFeGl0KTtcbiAgfTtcbiAgY29uc3Qgb25Qcm9jZXNzRXhpdCA9ICgpID0+IHtcbiAgICBpZiAoY2hpbGQpIGNoaWxkLmtpbGwoXCJTSUdURVJNXCIpO1xuICB9O1xuICBwcm9jZXNzLm9uY2UoXCJleGl0XCIsIG9uUHJvY2Vzc0V4aXQpO1xuXG4gIGNvbnN0IHJ1biA9IGFzeW5jICgpID0+IHtcbiAgICBsZXQgZmFpbHVyZXMgPSAwO1xuICAgIHdoaWxlICghY29udHJvbGxlci5zaWduYWwuYWJvcnRlZCkge1xuICAgICAgY29uc3Qgc3RhcnRlZEF0ID0gRGF0ZS5ub3coKTtcbiAgICAgIGxldCBvdXRjb21lOiBQcm9jZXNzT3V0Y29tZTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNoaWxkID0gYXdhaXQgb3B0aW9ucy5zdGFydCgpO1xuICAgICAgICBvdXRjb21lID0gYXdhaXQgcHJvY2Vzc091dGNvbWUoY2hpbGQsIGNvbnRyb2xsZXIuc2lnbmFsKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIG91dGNvbWUgPSB7IGVycm9yIH07XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBjaGlsZCA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGlmIChjb250cm9sbGVyLnNpZ25hbC5hYm9ydGVkKSByZXR1cm47XG4gICAgICBpZiAoRGF0ZS5ub3coKSAtIHN0YXJ0ZWRBdCA+PSBTVEFCTEVfQ09OTkVDVElPTl9NUykgZmFpbHVyZXMgPSAwO1xuICAgICAgY29uc3QgZGVsYXlNcyA9IGFzeW5jVG9vbHMuYm91bmRlZFJldHJ5RGVsYXkoZmFpbHVyZXMrKywgb3B0aW9ucy5yZXRyeURlbGF5c01zKTtcbiAgICAgIG9wdGlvbnMubG9nZ2VyLndhcm4oYCR7b3B0aW9ucy5uYW1lfSBzdG9wcGVkOyByZXRyeWluZ2AsIHsgLi4ub3V0Y29tZSwgZGVsYXlNcyB9KTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IGFzeW5jVG9vbHMuc2xlZXAoZGVsYXlNcywgY29udHJvbGxlci5zaWduYWwpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgdm9pZCBydW4oKS5jYXRjaCgoZXJyb3IpID0+IG9wdGlvbnMubG9nZ2VyLmVycm9yKGAke29wdGlvbnMubmFtZX0gc3VwZXJ2aXNvciBmYWlsZWRgLCB7IGVycm9yIH0pKTtcbiAgcmV0dXJuIHtcbiAgICBzdG9wLFxuICB9O1xufVxuXG5mdW5jdGlvbiBwcm9jZXNzT3V0Y29tZShjaGlsZDogQ2hpbGRQcm9jZXNzLCBzaWduYWw6IEFib3J0U2lnbmFsKTogUHJvbWlzZTxQcm9jZXNzT3V0Y29tZT4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICBjb25zdCBmaW5pc2ggPSAob3V0Y29tZTogUHJvY2Vzc091dGNvbWUpID0+IHtcbiAgICAgIGNoaWxkLm9mZihcImV4aXRcIiwgb25FeGl0KTtcbiAgICAgIGNoaWxkLm9mZihcImVycm9yXCIsIG9uRXJyb3IpO1xuICAgICAgc2lnbmFsLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJhYm9ydFwiLCBvbkFib3J0KTtcbiAgICAgIHJlc29sdmUob3V0Y29tZSk7XG4gICAgfTtcbiAgICBjb25zdCBvbkV4aXQgPSAoY29kZTogbnVtYmVyIHwgbnVsbCwgZXhpdFNpZ25hbDogTm9kZUpTLlNpZ25hbHMgfCBudWxsKSA9PlxuICAgICAgZmluaXNoKHsgY29kZSwgc2lnbmFsOiBleGl0U2lnbmFsIH0pO1xuICAgIGNvbnN0IG9uRXJyb3IgPSAoZXJyb3I6IEVycm9yKSA9PiB7XG4gICAgICBjaGlsZC5raWxsKFwiU0lHVEVSTVwiKTtcbiAgICAgIGZpbmlzaCh7IGVycm9yIH0pO1xuICAgIH07XG4gICAgY29uc3Qgb25BYm9ydCA9ICgpID0+IHtcbiAgICAgIGZpbmlzaCh7IHNpZ25hbDogXCJTSUdURVJNXCIgfSk7XG4gICAgfTtcbiAgICBjaGlsZC5vbmNlKFwiZXhpdFwiLCBvbkV4aXQpO1xuICAgIGNoaWxkLm9uY2UoXCJlcnJvclwiLCBvbkVycm9yKTtcbiAgICBzaWduYWwuYWRkRXZlbnRMaXN0ZW5lcihcImFib3J0XCIsIG9uQWJvcnQsIHsgb25jZTogdHJ1ZSB9KTtcbiAgfSk7XG59XG4iXX0=
package/package.json CHANGED
@@ -23,16 +23,16 @@
23
23
  "typescript": "^5.9.3"
24
24
  },
25
25
  "peerDependencies": {
26
- "@dbx-tools/email": "0.6.123"
26
+ "@dbx-tools/email": "0.6.125"
27
27
  },
28
28
  "dependencies": {
29
29
  "@databricks/appkit": "^0.60.0",
30
- "@dbx-tools/appkit": "0.6.123",
31
- "@dbx-tools/auth": "0.6.123",
32
- "@dbx-tools/core": "0.6.123",
33
- "@dbx-tools/email": "0.6.123",
34
- "@dbx-tools/shared-auth": "0.6.123",
35
- "@dbx-tools/shared-core": "0.6.123",
30
+ "@dbx-tools/appkit": "0.6.125",
31
+ "@dbx-tools/auth": "0.6.125",
32
+ "@dbx-tools/core": "0.6.125",
33
+ "@dbx-tools/email": "0.6.125",
34
+ "@dbx-tools/shared-auth": "0.6.125",
35
+ "@dbx-tools/shared-core": "0.6.125",
36
36
  "http-proxy-3": "^1.23.1"
37
37
  },
38
38
  "main": "./lib/index.js",
@@ -49,7 +49,7 @@
49
49
  "./package.json": "./package.json"
50
50
  }
51
51
  },
52
- "version": "0.6.123",
52
+ "version": "0.6.125",
53
53
  "types": "./lib/index.d.ts",
54
54
  "type": "module",
55
55
  "exports": {
@@ -60,13 +60,49 @@ export interface TunnelInterceptorOptions {
60
60
  /** Public tunnel clients supported by the interceptor and CLI. */
61
61
  export type TunnelTransport = "portr" | "frp" | "both";
62
62
 
63
+ interface TunnelAuxiliary {
64
+ stop(): void;
65
+ }
66
+
67
+ interface TunnelRuntime {
68
+ startPortr(config: NonNullable<ReturnType<typeof resolvePortrConfig>>): Promise<TunnelAuxiliary>;
69
+ startFrp(
70
+ config: NonNullable<ReturnType<typeof resolveFrpConfig>>,
71
+ ctx: InterceptorContext,
72
+ ): Promise<TunnelAuxiliary>;
73
+ }
74
+
75
+ const defaultRuntime: TunnelRuntime = {
76
+ async startPortr(config) {
77
+ const portrEnv = await installPortr();
78
+ await writePortrConfig(config, portrEnv);
79
+ return supervisePortr(config, portrEnv);
80
+ },
81
+ async startFrp(config, ctx) {
82
+ const pathProxy =
83
+ config.stripPrefix && config.path !== "/"
84
+ ? await startPathProxy(config.targetPort, config.path)
85
+ : undefined;
86
+ if (pathProxy) {
87
+ config.targetPort = pathProxy.port;
88
+ ctx.onLifecycle("shutdown", () => void pathProxy.close());
89
+ }
90
+ const frpEnv = await installFrp();
91
+ const configPath = await writeFrpConfig(config, frpEnv);
92
+ const supervisor = superviseFrp(config, frpEnv, configPath);
93
+ return {
94
+ stop() {
95
+ supervisor.stop();
96
+ void pathProxy?.close();
97
+ },
98
+ };
99
+ },
100
+ };
101
+
63
102
  /** Resolve and validate the tunnel transport selector. */
64
103
  export function resolveTunnelTransport(transport?: string): TunnelTransport {
65
104
  const resolved =
66
- transport ??
67
- process.env.DBX_TOOLS_TUNNEL_TRANSPORT ??
68
- process.env.TUNNEL_TRANSPORT ??
69
- "portr";
105
+ transport ?? process.env.DBX_TOOLS_TUNNEL_TRANSPORT ?? process.env.TUNNEL_TRANSPORT ?? "portr";
70
106
  if (resolved === "portr" || resolved === "frp" || resolved === "both") return resolved;
71
107
  throw new TypeError(`invalid tunnel transport: ${resolved} (expected portr, frp, or both)`);
72
108
  }
@@ -91,7 +127,10 @@ function resolvePublicPort(port?: number): number {
91
127
  * interceptor: tunnelInterceptor(),
92
128
  * });
93
129
  */
94
- export function tunnelInterceptor(options: TunnelInterceptorOptions = {}): Interceptor {
130
+ export function tunnelInterceptor(
131
+ options: TunnelInterceptorOptions = {},
132
+ runtime: TunnelRuntime = defaultRuntime,
133
+ ): Interceptor {
95
134
  return async (ctx: InterceptorContext): Promise<void> => {
96
135
  if (ctx.env.databricksHost) {
97
136
  process.env.DATABRICKS_HOST ??= ctx.env.databricksHost;
@@ -99,7 +138,7 @@ export function tunnelInterceptor(options: TunnelInterceptorOptions = {}): Inter
99
138
 
100
139
  const port = resolvePublicPort(options.port);
101
140
  const transport = resolveTunnelTransport(options.transport);
102
- const auxiliaries: Array<{ stop(): void }> = [];
141
+ const initializers: Array<Promise<TunnelAuxiliary>> = [];
103
142
  if (transport === "portr" || transport === "both") {
104
143
  const portrConfig = resolvePortrConfig({
105
144
  publicDomain: options.publicDomain,
@@ -107,9 +146,7 @@ export function tunnelInterceptor(options: TunnelInterceptorOptions = {}): Inter
107
146
  port,
108
147
  });
109
148
  if (portrConfig) {
110
- const portrEnv = await installPortr();
111
- await writePortrConfig(portrConfig, portrEnv);
112
- auxiliaries.push(supervisePortr(portrConfig, portrEnv));
149
+ initializers.push(runtime.startPortr(portrConfig));
113
150
  } else {
114
151
  logger.info("portr not configured (requires PORTR_TOKEN and TUNNEL_PUBLIC_DOMAIN)");
115
152
  }
@@ -127,28 +164,31 @@ export function tunnelInterceptor(options: TunnelInterceptorOptions = {}): Inter
127
164
  port,
128
165
  });
129
166
  if (frpConfig) {
130
- const pathProxy =
131
- frpConfig.stripPrefix && frpConfig.path !== "/"
132
- ? await startPathProxy(port, frpConfig.path)
133
- : undefined;
134
- if (pathProxy) {
135
- frpConfig.targetPort = pathProxy.port;
136
- ctx.onLifecycle("shutdown", () => void pathProxy.close());
137
- }
138
- const frpEnv = await installFrp();
139
- const configPath = await writeFrpConfig(frpConfig, frpEnv);
140
- auxiliaries.push(superviseFrp(frpConfig, frpEnv, configPath));
167
+ initializers.push(runtime.startFrp(frpConfig, ctx));
141
168
  } else {
142
169
  logger.info("frp not configured (requires TUNNEL_PUBLIC_DOMAIN)");
143
170
  }
144
171
  }
145
- if (!auxiliaries.length) return;
146
- ctx.onTeardown(() => {
147
- for (const auxiliary of auxiliaries) auxiliary.stop();
148
- });
149
- ctx.onLifecycle("shutdown", () => {
172
+ if (!initializers.length) return;
173
+ const auxiliaries: TunnelAuxiliary[] = [];
174
+ let stopped = false;
175
+ const stop = () => {
176
+ stopped = true;
150
177
  for (const auxiliary of auxiliaries) auxiliary.stop();
178
+ };
179
+ ctx.onTeardown(stop);
180
+ ctx.onLifecycle("shutdown", stop);
181
+ void Promise.allSettled(initializers).then((results) => {
182
+ for (const result of results) {
183
+ if (result.status === "rejected") {
184
+ logger.error("tunnel failed to start", { error: result.reason });
185
+ continue;
186
+ }
187
+ if (stopped) result.value.stop();
188
+ else auxiliaries.push(result.value);
189
+ }
190
+ if (!stopped && auxiliaries.length) logger.info(`tunnel bound: ${transport} -> :${port}`);
151
191
  });
152
- logger.info(`tunnel bound: ${transport} -> :${port}`);
192
+ logger.info(`tunnel initialization scheduled: ${transport} -> :${port}`);
153
193
  };
154
194
  }
package/src/supervisor.ts CHANGED
@@ -2,6 +2,7 @@ import type { ChildProcess } from "node:child_process";
2
2
  import { async as asyncTools, type Logger } from "@dbx-tools/shared-core";
3
3
 
4
4
  const STABLE_CONNECTION_MS = 60_000;
5
+ const DEFAULT_SHUTDOWN_GRACE_MS = 10_000;
5
6
 
6
7
  export interface ProcessSupervisor {
7
8
  stop(): void;
@@ -18,18 +19,29 @@ export function superviseProcessForever(options: {
18
19
  logger: Logger;
19
20
  start: () => ChildProcess | Promise<ChildProcess>;
20
21
  retryDelaysMs?: readonly number[];
22
+ shutdownGraceMs?: number;
21
23
  }): ProcessSupervisor {
22
24
  const controller = new AbortController();
23
25
  let child: ChildProcess | undefined;
24
26
 
27
+ const terminateChild = () => {
28
+ const stoppingChild = child;
29
+ if (!stoppingChild) return;
30
+ stoppingChild.kill("SIGTERM");
31
+ setTimeout(
32
+ () => stoppingChild.kill("SIGKILL"),
33
+ options.shutdownGraceMs ?? DEFAULT_SHUTDOWN_GRACE_MS,
34
+ ).unref();
35
+ };
36
+
25
37
  const stop = () => {
26
38
  if (controller.signal.aborted) return;
27
39
  controller.abort();
28
- if (child && !child.killed) child.kill("SIGTERM");
40
+ terminateChild();
29
41
  process.off("exit", onProcessExit);
30
42
  };
31
43
  const onProcessExit = () => {
32
- if (child && !child.killed) child.kill("SIGTERM");
44
+ if (child) child.kill("SIGTERM");
33
45
  };
34
46
  process.once("exit", onProcessExit);
35
47
 
@@ -75,11 +87,10 @@ function processOutcome(child: ChildProcess, signal: AbortSignal): Promise<Proce
75
87
  const onExit = (code: number | null, exitSignal: NodeJS.Signals | null) =>
76
88
  finish({ code, signal: exitSignal });
77
89
  const onError = (error: Error) => {
78
- if (!child.killed) child.kill("SIGTERM");
90
+ child.kill("SIGTERM");
79
91
  finish({ error });
80
92
  };
81
93
  const onAbort = () => {
82
- if (!child.killed) child.kill("SIGTERM");
83
94
  finish({ signal: "SIGTERM" });
84
95
  };
85
96
  child.once("exit", onExit);