@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.
- package/lib/src/interceptor.d.ts +12 -2
- package/lib/src/interceptor.js +53 -27
- package/lib/src/supervisor.d.ts +1 -0
- package/lib/src/supervisor.js +12 -8
- package/package.json +8 -8
- package/src/interceptor.ts +66 -26
- package/src/supervisor.ts +15 -4
package/lib/src/interceptor.d.ts
CHANGED
|
@@ -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 {};
|
package/lib/src/interceptor.js
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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 (!
|
|
115
|
+
if (!initializers.length)
|
|
105
116
|
return;
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
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
|
|
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==
|
package/lib/src/supervisor.d.ts
CHANGED
package/lib/src/supervisor.js
CHANGED
|
@@ -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
|
-
|
|
11
|
-
child.kill("SIGTERM");
|
|
18
|
+
terminateChild();
|
|
12
19
|
process.off("exit", onProcessExit);
|
|
13
20
|
};
|
|
14
21
|
const onProcessExit = () => {
|
|
15
|
-
if (child
|
|
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
|
-
|
|
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,
|
|
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.
|
|
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.
|
|
31
|
-
"@dbx-tools/auth": "0.6.
|
|
32
|
-
"@dbx-tools/core": "0.6.
|
|
33
|
-
"@dbx-tools/email": "0.6.
|
|
34
|
-
"@dbx-tools/shared-auth": "0.6.
|
|
35
|
-
"@dbx-tools/shared-core": "0.6.
|
|
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.
|
|
52
|
+
"version": "0.6.125",
|
|
53
53
|
"types": "./lib/index.d.ts",
|
|
54
54
|
"type": "module",
|
|
55
55
|
"exports": {
|
package/src/interceptor.ts
CHANGED
|
@@ -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(
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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 (!
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
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
|
|
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
|
-
|
|
40
|
+
terminateChild();
|
|
29
41
|
process.off("exit", onProcessExit);
|
|
30
42
|
};
|
|
31
43
|
const onProcessExit = () => {
|
|
32
|
-
if (child
|
|
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
|
-
|
|
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);
|