@dbx-tools/cli-tunnel 0.6.105 → 0.6.107
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/README.md +26 -14
- package/lib/src/cli.js +31 -11
- package/lib/src/options.d.ts +10 -1
- package/lib/src/options.js +14 -2
- package/package.json +8 -8
- package/src/cli.ts +29 -11
- package/src/options.ts +22 -1
package/README.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# @dbx-tools/cli-tunnel
|
|
2
2
|
|
|
3
|
-
Wrap any command in a public [
|
|
4
|
-
|
|
3
|
+
Wrap any command in a public [Portr](https://github.com/amalshaji/portr),
|
|
4
|
+
[FRP](https://github.com/fatedier/frp), or combined tunnel fronted by
|
|
5
|
+
[`@dbx-tools/auth`](../../node/auth) email OTP and passkeys.
|
|
5
6
|
|
|
6
7
|
Run `dbx tunnel -- <command>` when a local or self-hosted process needs a public
|
|
7
8
|
URL that only approved email addresses can reach. The wrapper claims the public
|
|
@@ -11,12 +12,12 @@ about.
|
|
|
11
12
|
|
|
12
13
|
Key features:
|
|
13
14
|
|
|
14
|
-
-
|
|
15
|
+
- Portr, FRP, or both tunnel clients + a Better Auth passwordless gate around a command the
|
|
15
16
|
wrapper does not have to modify, import, or even be written in the same
|
|
16
17
|
language as.
|
|
17
18
|
- A reverse proxy that answers the login routes itself and forwards only
|
|
18
19
|
verified traffic to the wrapped process.
|
|
19
|
-
- Flag → environment → `databricks.yml` resolution for every gate and
|
|
20
|
+
- Flag → environment → `databricks.yml` resolution for every gate and tunnel
|
|
20
21
|
setting, delegated to [`@dbx-tools/tunnel`](../../node/tunnel) so the CLI
|
|
21
22
|
cannot drift from the in-process plugin.
|
|
22
23
|
- The same server-less `appkit.createApp` lifecycle as plugin mode. It can
|
|
@@ -75,16 +76,20 @@ subcommand, so `dbx tunnel -- cmd` and `dbx tunnel run -- cmd` are equivalent.
|
|
|
75
76
|
dbx tunnel status --allow databricks.com
|
|
76
77
|
```
|
|
77
78
|
|
|
78
|
-
The most common failure is a tunnel that silently does nothing because
|
|
79
|
-
|
|
80
|
-
config, and
|
|
79
|
+
The most common failure is a tunnel that silently does nothing because its
|
|
80
|
+
credentials or public domain did not resolve. `status` prints the fully resolved
|
|
81
|
+
ports, gate config, and client configs as JSON without starting a process.
|
|
81
82
|
|
|
82
83
|
```sh
|
|
83
84
|
dbx tunnel install
|
|
84
85
|
```
|
|
85
86
|
|
|
86
|
-
`install`
|
|
87
|
-
|
|
87
|
+
`install` defaults to Portr. Pass `frp` or `both` to preinstall those clients:
|
|
88
|
+
|
|
89
|
+
```sh
|
|
90
|
+
dbx tunnel install frp
|
|
91
|
+
dbx tunnel install both
|
|
92
|
+
```
|
|
88
93
|
|
|
89
94
|
## Commands And Flags
|
|
90
95
|
|
|
@@ -92,7 +97,7 @@ the download.
|
|
|
92
97
|
dbx tunnel [options] -- <command...> # wrap a command (default)
|
|
93
98
|
dbx tunnel run [options] -- <command...>
|
|
94
99
|
dbx tunnel status [options]
|
|
95
|
-
dbx tunnel install
|
|
100
|
+
dbx tunnel install [portr|frp|both]
|
|
96
101
|
```
|
|
97
102
|
|
|
98
103
|
Every flag below is accepted on the root command and on `run` / `status`.
|
|
@@ -101,8 +106,15 @@ Omitted values fall back to the environment, a `.env` file, then
|
|
|
101
106
|
|
|
102
107
|
| Flag | Meaning |
|
|
103
108
|
| ----------------------------- | ---------------------------------------------------------- |
|
|
104
|
-
| `--
|
|
109
|
+
| `--transport <mode>` | `portr` (default), `frp`, or `both` |
|
|
110
|
+
| `--public-domain <host>` | Portr public domain (`<subdomain>.<server>`) |
|
|
105
111
|
| `--subdomain <name>` | portr subdomain, else derived from the public domain |
|
|
112
|
+
| `--frp-public-domain <host>` | FRP public HTTP domain |
|
|
113
|
+
| `--frp-server <host>` | frps control host, else the FRP public domain |
|
|
114
|
+
| `--frp-server-port <port>` | frps control port (default `443`) |
|
|
115
|
+
| `--frp-protocol <protocol>` | frpc transport protocol (default `wss`) |
|
|
116
|
+
| `--frp-token <token>` | optional frps auth token |
|
|
117
|
+
| `--frp-proxy-name <name>` | frp proxy name, else the domain's first label |
|
|
106
118
|
| `--port <port>` | public port the wrapper listens on (`DATABRICKS_APP_PORT`) |
|
|
107
119
|
| `--app-port <port>` | private port the wrapped app binds, else a free one |
|
|
108
120
|
| `--allow <patterns...>` | email allow-list (domain, glob, or `/regex/`) |
|
|
@@ -126,7 +138,7 @@ local debugging, not for anything reachable.
|
|
|
126
138
|
|
|
127
139
|
## How A Request Flows
|
|
128
140
|
|
|
129
|
-
1. The wrapper binds the PUBLIC port - the one
|
|
141
|
+
1. The wrapper binds the PUBLIC port - the one tunnel clients and Databricks Apps
|
|
130
142
|
runtime route to - and spawns the command on a private loopback port.
|
|
131
143
|
2. A login route (`/auth/*`) is answered by the proxy itself, using the gate
|
|
132
144
|
handlers from a server-less AppKit app that supplies the code store, signing
|
|
@@ -134,8 +146,8 @@ local debugging, not for anything reachable.
|
|
|
134
146
|
3. Anything else goes through `gate.gateRequest`. A verified session is proxied
|
|
135
147
|
to the child with caller-supplied `x-` headers stripped; an unverified
|
|
136
148
|
request gets the login page or a `401`.
|
|
137
|
-
4.
|
|
138
|
-
|
|
149
|
+
4. The selected client(s) publish the public port. In `both` mode, configure
|
|
150
|
+
different Portr and FRP domains; the gate recognizes both hosts.
|
|
139
151
|
|
|
140
152
|
## Modules
|
|
141
153
|
|
package/lib/src/cli.js
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
import { spawn } from "node:child_process";
|
|
25
25
|
import { createServer } from "node:net";
|
|
26
26
|
import { log } from "@dbx-tools/shared-core";
|
|
27
|
-
import { portr } from "@dbx-tools/tunnel";
|
|
27
|
+
import { frp, portr } from "@dbx-tools/tunnel";
|
|
28
28
|
import { Command, CommanderError } from "commander";
|
|
29
29
|
import { resolveTunnelOptions } from "./options.js";
|
|
30
30
|
import { startProxy } from "./proxy.js";
|
|
@@ -55,7 +55,8 @@ function freePort() {
|
|
|
55
55
|
*/
|
|
56
56
|
function addOptions(command) {
|
|
57
57
|
return command
|
|
58
|
-
.option("--
|
|
58
|
+
.option("--transport <transport>", "public tunnel transport: portr, frp, or both")
|
|
59
|
+
.option("--public-domain <host>", "public tunnel domain")
|
|
59
60
|
.option("--subdomain <name>", "portr subdomain (else derived from the public domain)")
|
|
60
61
|
.option("--port <port>", "public port the wrapper listens on")
|
|
61
62
|
.option("--app-port <port>", "private port the wrapped app is told to bind")
|
|
@@ -71,6 +72,12 @@ function addOptions(command) {
|
|
|
71
72
|
.option("--forward-headers <patterns...>", "extra x- headers tunnel traffic may forward")
|
|
72
73
|
.option("--gate-path <prefix...>", "path prefixes to gate beyond /api/ (e.g. /ws)")
|
|
73
74
|
.option("--bind <host...>", "interface IPs the gate listens on (default: 0.0.0.0)")
|
|
75
|
+
.option("--frp-server <host>", "frps control host (default: FRP public domain)")
|
|
76
|
+
.option("--frp-public-domain <host>", "FRP public HTTP domain")
|
|
77
|
+
.option("--frp-server-port <port>", "frps control port (default: 443)")
|
|
78
|
+
.option("--frp-protocol <protocol>", "frpc transport protocol (default: wss)")
|
|
79
|
+
.option("--frp-token <token>", "frps auth token")
|
|
80
|
+
.option("--frp-proxy-name <name>", "frp proxy registration name")
|
|
74
81
|
.option("--insecure", "run open, with no gate");
|
|
75
82
|
}
|
|
76
83
|
/**
|
|
@@ -147,23 +154,29 @@ async function run(raw, command) {
|
|
|
147
154
|
brandName: resolved.gate.brandName,
|
|
148
155
|
bindHosts: resolved.bindHosts,
|
|
149
156
|
});
|
|
150
|
-
if (resolved.portr) {
|
|
157
|
+
if ((resolved.transport === "portr" || resolved.transport === "both") && resolved.portr) {
|
|
151
158
|
const portrEnv = await portr.installPortr();
|
|
152
159
|
await portr.writePortrConfig(resolved.portr, portrEnv);
|
|
153
160
|
children.push(await portr.startPortr(resolved.portr, portrEnv));
|
|
154
161
|
}
|
|
155
|
-
|
|
156
|
-
|
|
162
|
+
if ((resolved.transport === "frp" || resolved.transport === "both") && resolved.frp) {
|
|
163
|
+
const frpEnv = await frp.installFrp();
|
|
164
|
+
const configPath = await frp.writeFrpConfig(resolved.frp, frpEnv);
|
|
165
|
+
children.push(frp.startFrp(resolved.frp, frpEnv, configPath));
|
|
166
|
+
}
|
|
167
|
+
const activeTunnelCount = children.length - (executable ? 1 : 0);
|
|
168
|
+
if (!activeTunnelCount)
|
|
169
|
+
logger.info("no selected public tunnel is configured", {
|
|
170
|
+
transport: resolved.transport,
|
|
157
171
|
publicPort: resolved.publicPort,
|
|
158
172
|
});
|
|
159
|
-
}
|
|
160
173
|
supervise(children);
|
|
161
174
|
}
|
|
162
175
|
/** The `dbx tunnel` program. No side effects until parsed. */
|
|
163
176
|
export function buildProgram(name = "dbx tunnel") {
|
|
164
177
|
const program = addOptions(new Command()
|
|
165
178
|
.name(name)
|
|
166
|
-
.description("Front a command with a
|
|
179
|
+
.description("Front a command with a public tunnel and passwordless auth"));
|
|
167
180
|
// `run` is the DEFAULT action as well as a named subcommand, preserving the old
|
|
168
181
|
// wrapper's ergonomics (`dbx tunnel --allow x -- bun src/server.ts`) while
|
|
169
182
|
// leaving somewhere for `status` and `install` to live.
|
|
@@ -186,10 +199,17 @@ export function buildProgram(name = "dbx tunnel") {
|
|
|
186
199
|
});
|
|
187
200
|
program
|
|
188
201
|
.command("install")
|
|
189
|
-
.
|
|
190
|
-
.
|
|
191
|
-
|
|
202
|
+
.argument("[transport]", "portr, frp, or both", "portr")
|
|
203
|
+
.description("Install public tunnel client binaries and exit")
|
|
204
|
+
.action(async (transport) => {
|
|
205
|
+
if (transport === "portr" || transport === "both")
|
|
206
|
+
await portr.installPortr();
|
|
207
|
+
if (transport === "frp" || transport === "both")
|
|
208
|
+
await frp.installFrp();
|
|
209
|
+
if (transport !== "portr" && transport !== "frp" && transport !== "both") {
|
|
210
|
+
throw new CommanderError(1, "tunnel.invalid-transport", `invalid transport: ${transport}`);
|
|
211
|
+
}
|
|
192
212
|
});
|
|
193
213
|
return program;
|
|
194
214
|
}
|
|
195
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NsaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXNCRztBQUVILE9BQU8sRUFBcUIsS0FBSyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDOUQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUN4QyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3BELE9BQU8sRUFBRSxvQkFBb0IsRUFBc0IsTUFBTSxjQUFjLENBQUM7QUFDeEUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUV4QyxPQUFPLEVBQUUsY0FBYyxFQUFFLENBQUM7QUFFMUIsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUVwQyxpRkFBaUY7QUFDakYsTUFBTSxpQkFBaUIsR0FBRyxLQUFLLENBQUM7QUFFaEM7Ozs7R0FJRztBQUNILFNBQVMsUUFBUTtJQUNmLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDckMsTUFBTSxLQUFLLEdBQUcsWUFBWSxFQUFFLENBQUM7UUFDN0IsS0FBSyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDMUIsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsV0FBVyxFQUFFLEdBQUcsRUFBRTtZQUNoQyxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDaEMsTUFBTSxJQUFJLEdBQUcsT0FBTyxPQUFPLEtBQUssUUFBUSxJQUFJLE9BQU8sQ0FBQyxD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QUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNqRSxDQUFDLENBQUMsQ0FBQztJQUVILE9BQU87U0FDSixPQUFPLENBQUMsU0FBUyxDQUFDO1NBQ2xCLFdBQVcsQ0FBQyxtQ0FBbUMsQ0FBQztTQUNoRCxNQUFNLENBQUMsS0FBSyxJQUFJLEVBQUU7UUFDakIsTUFBTSxLQUFLLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDN0IsQ0FBQyxDQUFDLENBQUM7SUFFTCxPQUFPLE9BQU8sQ0FBQztBQUNqQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBgZGJ4IHR1bm5lbGAgLSBmcm9udCBhIGNvbW1hbmQgd2l0aCBhIHB1YmxpYyBwb3J0ciB0dW5uZWwgYW5kIHBhc3N3b3JkbGVzcyBnYXRlLlxuICpcbiAqIFRoaXMgaXMgdGhlIFdSQVBQRVIgcGF0aCwgYW5kIGl0IGV4aXN0cyBmb3Igb25lIGNhc2U6IGEgcHJvamVjdCB0aGF0IGRvZXMgbm90XG4gKiB1c2UgYEBkYngtdG9vbHMvYXBwa2l0YCdzIGBjcmVhdGVBcHBgLCBhbmQgdGhlcmVmb3JlIGNhbm5vdCByZWdpc3RlclxuICogYHR1bm5lbEludGVyY2VwdG9yKClgICsgdGhlIGBhdXRoR2F0ZWAgcGx1Z2luIGluLXByb2Nlc3MuIEFuIEFwcEtpdCBhcHAgc2hvdWxkXG4gKiBzdGlsbCB0YWtlIHRoZSBwbHVnaW4gcGF0aCAtIG9uZSBwcm9jZXNzLCBubyBwcm94eSBob3AsIG5vIGR1cGxpY2F0ZWQgaGVhZGVyXG4gKiBoYW5kbGluZy5cbiAqXG4gKiBUaGUgd3JhcHBlciBjbGFpbXMgdGhlIFBVQkxJQyBwb3J0IChgREFUQUJSSUNLU19BUFBfUE9SVGAsIHRoZSBwb3J0IHRoZVxuICogcGxhdGZvcm0gYW5kIHBvcnRyIHJvdXRlIHRvKSwgbW92ZXMgdGhlIHdyYXBwZWQgYXBwIHRvIGEgcHJpdmF0ZSBvbmUsIGFuZFxuICogcmV2ZXJzZS1wcm94aWVzIGJldHdlZW4gdGhlbSBzbyB0aGUgZ2F0ZSBzaXRzIGluIGZyb250IG9mIHRyYWZmaWMgaXQgd291bGRcbiAqIG90aGVyd2lzZSBoYXZlIG5vIHdheSB0byBpbnRlcmNlcHQuIEV2ZXJ5dGhpbmcgZWxzZSBpcyBkZWxlZ2F0ZWQ6IHRoZSBnYXRlXG4gKiBjb25maWcgY29tZXMgZnJvbSBgcGx1Z2luLnJlc29sdmVBdXRoR2F0ZUNvbmZpZ2AsIHRoZSBwb3J0ciBsaWZlY3ljbGUgZnJvbVxuICogYHBvcnRyLipgIC0gYm90aCB0aGUgc2FtZSBmdW5jdGlvbnMgdGhlIGluLXByb2Nlc3MgcGF0aCB1c2VzLlxuICpcbiAqIFNoaXBzIG5vIGJpbi4gYEBkYngtdG9vbHMvY2xpYCBtb3VudHMgYGJ1aWxkUHJvZ3JhbSgpYCBhcyBgZGJ4IHR1bm5lbGAgbGF6aWx5LFxuICogc28gYGRieCBkZXZgIHBheXMgZm9yIG5vbmUgb2YgdGhpcywgYW5kIGAtLWluc2VjdXJlYCAvIGBzdGF0dXNgIC8gYGluc3RhbGxgXG4gKiBuZXZlciBsb2FkIEFwcEtpdCBvciB0aGUgU01UUCBzdGFjayBlaXRoZXIgKHRoZSBnYXRlIGFwcCBpcyBiZWhpbmQgYSBkeW5hbWljXG4gKiBpbXBvcnQpLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyB0eXBlIENoaWxkUHJvY2Vzcywgc3Bhd24gfSBmcm9tIFwibm9kZTpjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgeyBjcmVhdGVTZXJ2ZXIgfSBmcm9tIFwibm9kZTpuZXRcIjtcbmltcG9ydCB7IGxvZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgeyBwb3J0ciB9IGZyb20gXCJAZGJ4LXRvb2xzL3R1bm5lbFwiO1xuaW1wb3J0IHsgQ29tbWFuZCwgQ29tbWFuZGVyRXJyb3IgfSBmcm9tIFwiY29tbWFuZGVyXCI7XG5pbXBvcnQgeyByZXNvbHZlVHVubmVsT3B0aW9ucywgdHlwZSBUdW5uZWxPcHRpb25zIH0gZnJvbSBcIi4vb3B0aW9ucy50c1wiO1xuaW1wb3J0IHsgc3RhcnRQcm94eSB9IGZyb20gXCIuL3Byb3h5LnRzXCI7XG5cbmV4cG9ydCB7IENvbW1hbmRlckVycm9yIH07XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJ0dW5uZWxcIik7XG5cbi8qKiBIb3cgbG9uZyBhIGNoaWxkIGdldHMgdG8gZXhpdCBvbiBTSUdURVJNIGJlZm9yZSB0aGUgd3JhcHBlciBsZWF2ZXMgYW55d2F5LiAqL1xuY29uc3QgU0hVVERPV05fR1JBQ0VfTVMgPSAzXzAwMDtcblxuLyoqXG4gKiBBIGZyZWUgbG9vcGJhY2sgcG9ydCwgZnJvbSB0aGUgT1MgcmF0aGVyIHRoYW4gYSByYW5kb20gZ3Vlc3M6IGJpbmRpbmcgYDBgIGFuZFxuICogcmVhZGluZyBiYWNrIHdoYXQgd2FzIGFzc2lnbmVkIGlzIHRoZSBvbmx5IHdheSB0byBrbm93IHRoZSBwb3J0IGlzIGFjdHVhbGx5XG4gKiBhdmFpbGFibGUsIHNvIHR3byB0dW5uZWxzIGNhbiBydW4gc2lkZSBieSBzaWRlIHdpdGhvdXQgY29sbGlkaW5nLlxuICovXG5mdW5jdGlvbiBmcmVlUG9ydCgpOiBQcm9taXNlPG51bWJlcj4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IHByb2JlID0gY3JlYXRlU2VydmVyKCk7XG4gICAgcHJvYmUub24oXCJlcnJvclwiLCByZWplY3QpO1xuICAgIHByb2JlLmxpc3RlbigwLCBcIjEyNy4wLjAuMVwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBhZGRyZXNzID0gcHJvYmUuYWRkcmVzcygpO1xuICAgICAgY29uc3QgcG9ydCA9IHR5cGVvZiBhZGRyZXNzID09PSBcIm9iamVjdFwiICYmIGFkZHJlc3MgPyBhZGRyZXNzLnBvcnQgOiAwO1xuICAgICAgcHJvYmUuY2xvc2UoKCkgPT4gKHBvcnQgPiAwID8gcmVzb2x2ZShwb3J0KSA6IHJlamVjdChuZXcgRXJyb3IoXCJubyBmcmVlIHBvcnRcIikpKSk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG4vKipcbiAqIEV2ZXJ5IGdhdGUvcG9ydHIgZmxhZy4gRGVjbGFyZWQgb24gdGhlIHJvb3QgY29tbWFuZCBBTkQgb24gYHJ1bmAvYHN0YXR1c2Agc29cbiAqIGBkYnggdHVubmVsIC0tYWxsb3cgeCAtLSBjbWRgIGFuZCBgZGJ4IHR1bm5lbCBydW4gLS1hbGxvdyB4IC0tIGNtZGAgYmVoYXZlXG4gKiBpZGVudGljYWxseSAtIGNvbW1hbmRlciBkb2VzIG5vdCBpbmhlcml0IG9wdGlvbnMgZG93bndhcmQuXG4gKi9cbmZ1bmN0aW9uIGFkZE9wdGlvbnMoY29tbWFuZDogQ29tbWFuZCk6IENvbW1hbmQge1xuICByZXR1cm4gY29tbWFuZFxuICAgIC5vcHRpb24oXCItLXB1YmxpYy1kb21haW4gPGhvc3Q+XCIsIFwicG9ydHIgcHVibGljIGRvbWFpbiAoPHN1YmRvbWFpbj4uPHNlcnZlcj4pXCIpXG4gICAgLm9wdGlvbihcIi0tc3ViZG9tYWluIDxuYW1lPlwiLCBcInBvcnRyIHN1YmRvbWFpbiAoZWxzZSBkZXJpdmVkIGZyb20gdGhlIHB1YmxpYyBkb21haW4pXCIpXG4gICAgLm9wdGlvbihcIi0tcG9ydCA8cG9ydD5cIiwgXCJwdWJsaWMgcG9ydCB0aGUgd3JhcHBlciBsaXN0ZW5zIG9uXCIpXG4gICAgLm9wdGlvbihcIi0tYXBwLXBvcnQgPHBvcnQ+XCIsIFwicHJpdmF0ZSBwb3J0IHRoZSB3cmFwcGVkIGFwcCBpcyB0b2xkIHRvIGJpbmRcIilcbiAgICAub3B0aW9uKFwiLS1hbGxvdyA8cGF0dGVybnMuLi4+XCIsIFwiZW1haWwgYWxsb3ctbGlzdCAoZG9tYWluIC8gZ2xvYiAvIC9yZWdleC8pXCIpXG4gICAgLm9wdGlvbihcIi0tc3ViamVjdCA8dGV4dD5cIiwgXCJ2ZXJpZmljYXRpb24gZW1haWwgc3ViamVjdFwiKVxuICAgIC5vcHRpb24oXCItLWJyYW5kLW5hbWUgPG5hbWU+XCIsIFwidmVyaWZpY2F0aW9uIGVtYWlsIGJyYW5kIG5hbWVcIilcbiAgICAub3B0aW9uKFwiLS1tZXNzYWdlIDx0ZXh0PlwiLCBcInZlcmlmaWNhdGlvbiBlbWFpbCBtZXNzYWdlXCIpXG4gICAgLm9wdGlvbihcIi0tc2Vzc2lvbi10dGwgPHNlY29uZHM+XCIsIFwic2Vzc2lvbiBsaWZldGltZVwiKVxuICAgIC5vcHRpb24oXCItLWNvZGUtdHRsIDxzZWNvbmRzPlwiLCBcIm9uZS10aW1lLWNvZGUgbGlmZXRpbWVcIilcbiAgICAub3B0aW9uKFwiLS1zZXNzaW9uLWN1dG9mZiA8d2hlbj5cIiwgXCJpbnZhbGlkYXRlIGV2ZXJ5IHNlc3Npb24gaXNzdWVkIGJlZm9yZSB0aGlzXCIpXG4gICAgLm9wdGlvbihcIi0tYXV0aC1zdG9yYWdlIDxtb2RlPlwiLCBcImF1dGggZGF0YWJhc2U6IGF1dG8sIGxha2ViYXNlLCBvciBzcWxpdGVcIilcbiAgICAub3B0aW9uKFwiLS1hdXRoLXNxbGl0ZS1wYXRoIDxwYXRoPlwiLCBcImxvY2FsIEJldHRlciBBdXRoIFNRTGl0ZSBmaWxlXCIpXG4gICAgLm9wdGlvbihcIi0tZm9yd2FyZC1oZWFkZXJzIDxwYXR0ZXJucy4uLj5cIiwgXCJleHRyYSB4LSBoZWFkZXJzIHR1bm5lbCB0cmFmZmljIG1heSBmb3J3YXJkXCIpXG4gICAgLm9wdGlvbihcIi0tZ2F0ZS1wYXRoIDxwcmVmaXguLi4+XCIsIFwicGF0aCBwcmVmaXhlcyB0byBnYXRlIGJleW9uZCAvYXBpLyAoZS5nLiAvd3MpXCIpXG4gICAgLm9wdGlvbihcIi0tYmluZCA8aG9zdC4uLj5cIiwgXCJpbnRlcmZhY2UgSVBzIHRoZSBnYXRlIGxpc3RlbnMgb24gKGRlZmF1bHQ6IDAuMC4wLjApXCIpXG4gICAgLm9wdGlvbihcIi0taW5zZWN1cmVcIiwgXCJydW4gb3Blbiwgd2l0aCBubyBnYXRlXCIpO1xufVxuXG4vKipcbiAqIFRpZSB0aGUgd3JhcHBlcidzIGxpZmV0aW1lIHRvIGl0cyBjaGlsZHJlbidzLCBpbiBib3RoIGRpcmVjdGlvbnM6IGEgY2hpbGQgdGhhdFxuICogZXhpdHMgdGFrZXMgdGhlIHdyYXBwZXIgZG93biB3aXRoIGl0cyBjb2RlLCBhbmQgYSBzaWduYWwgdG8gdGhlIHdyYXBwZXIgaXNcbiAqIGZvcndhcmRlZCBiZWZvcmUgaXQgbGVhdmVzLiBXaXRob3V0IHRoaXMgYSBjcmFzaGVkIGFwcCBsZWF2ZXMgYSBwb3J0ciB0dW5uZWxcbiAqIHNlcnZpbmcgYSBkZWFkIHBvcnQsIHdoaWNoIGxvb2tzIGxpa2UgYSBoYW5nIHJhdGhlciB0aGFuIGEgZmFpbHVyZS5cbiAqL1xuZnVuY3Rpb24gc3VwZXJ2aXNlKGNoaWxkcmVuOiByZWFkb25seSBDaGlsZFByb2Nlc3NbXSk6IHZvaWQge1xuICBsZXQgc3RvcHBpbmcgPSBmYWxzZTtcbiAgY29uc3Qgc3RvcCA9IChjb2RlOiBudW1iZXIpOiB2b2lkID0+IHtcbiAgICBpZiAoc3RvcHBpbmcpIHJldHVybjtcbiAgICBzdG9wcGluZyA9IHRydWU7XG4gICAgZm9yIChjb25zdCBjaGlsZCBvZiBjaGlsZHJlbikgaWYgKCFjaGlsZC5raWxsZWQpIGNoaWxkLmtpbGwoXCJTSUdURVJNXCIpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4gcHJvY2Vzcy5leGl0KGNvZGUpLCBTSFVURE9XTl9HUkFDRV9NUykudW5yZWYoKTtcbiAgfTtcbiAgZm9yIChjb25zdCBjaGlsZCBvZiBjaGlsZHJlbikgY2hpbGQub24oXCJleGl0XCIsIChjb2RlKSA9PiBzdG9wKGNvZGUgPz8gMSkpO1xuICBmb3IgKGNvbnN0IHNpZ25hbCBvZiBbXCJTSUdURVJNXCIsIFwiU0lHSU5UXCIsIFwiU0lHSFVQXCJdIGFzIGNvbnN0KSB7XG4gICAgcHJvY2Vzcy5vbihzaWduYWwsICgpID0+IHN0b3AoMCkpO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJ1bihyYXc6IFR1bm5lbE9wdGlvbnMsIGNvbW1hbmQ6IHJlYWRvbmx5IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IFtleGVjdXRhYmxlLCAuLi5hcmdzXSA9IGNvbW1hbmQ7XG4gIGNvbnN0IHJlc29sdmVkID0gcmVzb2x2ZVR1bm5lbE9wdGlvbnMocmF3KTtcbiAgY29uc3QgY2hpbGRyZW46IENoaWxkUHJvY2Vzc1tdID0gW107XG5cbiAgLy8gVHdvIHVwc3RyZWFtIG1vZGVzOlxuICAvLyAgIC0gV1JBUDogYSBjb21tYW5kIGFmdGVyIGAtLWAuIFRoZSB3cmFwcGVyIHNwYXducyBpdCBvbiBhIHByaXZhdGUgbG9vcGJhY2tcbiAgLy8gICAgIHBvcnQgYW5kIGlzIHRoZSBvbmx5IHRoaW5nIHRoYXQgdGFsa3MgdG8gaXQuXG4gIC8vICAgLSBBVFRBQ0g6IG5vIGNvbW1hbmQsIGJ1dCBgLS1hcHAtcG9ydGAgbmFtZXMgYW4gYWxyZWFkeS1ydW5uaW5nIHVwc3RyZWFtXG4gIC8vICAgICAoZS5nLiBhIGxvY2FsIHJldmVyc2UgcHJveHkpLiBUaGUgZ2F0ZSBmcm9udHMgaXQgd2l0aG91dCBzcGF3bmluZyBhXG4gIC8vICAgICBjaGlsZC4gVGhpcyBpcyB3aGF0IGxldHMgdGhlIGdhdGUgc2l0IG9uIGFuIGludGVyZmFjZSBpbiBmcm9udCBvZiBhXG4gIC8vICAgICBzZXBhcmF0ZWx5LXN1cGVydmlzZWQgc3RhY2suXG4gIGxldCBhcHBQb3J0OiBudW1iZXI7XG4gIGlmIChleGVjdXRhYmxlKSB7XG4gICAgYXBwUG9ydCA9IHJlc29sdmVkLmFwcFBvcnQgPz8gKGF3YWl0IGZyZWVQb3J0KCkpO1xuICAgIGNvbnN0IGFwcCA9IHNwYXduKGV4ZWN1dGFibGUsIGFyZ3MsIHtcbiAgICAgIGVudjoge1xuICAgICAgICAuLi5wcm9jZXNzLmVudixcbiAgICAgICAgREFUQUJSSUNLU19BUFBfUE9SVDogU3RyaW5nKGFwcFBvcnQpLFxuICAgICAgICBQT1JUOiBTdHJpbmcoYXBwUG9ydCksXG4gICAgICAgIEhPU1Q6IFwiMTI3LjAuMC4xXCIsXG4gICAgICB9LFxuICAgICAgc3RkaW86IFwiaW5oZXJpdFwiLFxuICAgIH0pO1xuICAgIGNoaWxkcmVuLnB1c2goYXBwKTtcbiAgfSBlbHNlIGlmIChyZXNvbHZlZC5hcHBQb3J0KSB7XG4gICAgYXBwUG9ydCA9IHJlc29sdmVkLmFwcFBvcnQ7XG4gICAgbG9nZ2VyLmluZm8oXCJhdHRhY2hpbmcgZ2F0ZSB0byBleGlzdGluZyB1cHN0cmVhbVwiLCB7IGFwcFBvcnQgfSk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IENvbW1hbmRlckVycm9yKFxuICAgICAgMSxcbiAgICAgIFwidHVubmVsLm5vLXVwc3RyZWFtXCIsXG4gICAgICBcIm5vIGNvbW1hbmQgZ2l2ZW4gKHBhc3MgaXQgYWZ0ZXIgYC0tYCkgYW5kIG5vIC0tYXBwLXBvcnQgdG8gYXR0YWNoIHRvXCIsXG4gICAgKTtcbiAgfVxuXG4gIC8vIER5bmFtaWMgaW1wb3J0OiB0aGUgZ2F0ZSBpcyB0aGUgb25seSB0aGluZyBoZXJlIHRoYXQgbmVlZHMgQXBwS2l0ICsgU01UUCwgc29cbiAgLy8gYW4gYC0taW5zZWN1cmVgIHJ1biBuZXZlciBsb2FkcyBlaXRoZXIuXG4gIGNvbnN0IGdhdGUgPSByZXNvbHZlZC5nYXRlLmluc2VjdXJlXG4gICAgPyB1bmRlZmluZWRcbiAgICA6IGF3YWl0IChcbiAgICAgICAgYXdhaXQgaW1wb3J0KFwiLi9hcHAudHNcIilcbiAgICAgICkuc3RhcnRHYXRlQXBwKHtcbiAgICAgICAgLi4ucmVzb2x2ZWQuZ2F0ZUNvbmZpZyxcbiAgICAgICAgcHVibGljRG9tYWluOiByZXNvbHZlZC5nYXRlLnB1YmxpY0RvbWFpbiA/PyBgbG9jYWxob3N0OiR7cmVzb2x2ZWQucHVibGljUG9ydH1gLFxuICAgICAgfSk7XG4gIGlmICghZ2F0ZSkgbG9nZ2VyLndhcm4oXCJydW5uaW5nIE9QRU4gLSBubyBnYXRlIGlzIGluIGZyb250IG9mIHRoaXMgdHVubmVsXCIpO1xuXG4gIGF3YWl0IHN0YXJ0UHJveHkoe1xuICAgIHB1YmxpY1BvcnQ6IHJlc29sdmVkLnB1YmxpY1BvcnQsXG4gICAgYXBwUG9ydCxcbiAgICBnYXRlLFxuICAgIGZvcndhcmRIZWFkZXJzOiByZXNvbHZlZC5nYXRlLmZvcndhcmRIZWFkZXJzLFxuICAgIGdhdGVQYXRoczogcmVzb2x2ZWQuZ2F0ZS5nYXRlUGF0aHMsXG4gICAgYnJhbmROYW1lOiByZXNvbHZlZC5nYXRlLmJyYW5kTmFtZSxcbiAgICBiaW5kSG9zdHM6IHJlc29sdmVkLmJpbmRIb3N0cyxcbiAgfSk7XG5cbiAgaWYgKHJlc29sdmVkLnBvcnRyKSB7XG4gICAgY29uc3QgcG9ydHJFbnYgPSBhd2FpdCBwb3J0ci5pbnN0YWxsUG9ydHIoKTtcbiAgICBhd2FpdCBwb3J0ci53cml0ZVBvcnRyQ29uZmlnKHJlc29sdmVkLnBvcnRyLCBwb3J0ckVudik7XG4gICAgY2hpbGRyZW4ucHVzaChhd2FpdCBwb3J0ci5zdGFydFBvcnRyKHJlc29sdmVkLnBvcnRyLCBwb3J0ckVudikpO1xuICB9IGVsc2Uge1xuICAgIGxvZ2dlci5pbmZvKFwibm8gUE9SVFJfVE9LRU4gLyBUVU5ORUxfUFVCTElDX0RPTUFJTiAtIHNlcnZpbmcgbG9jYWxseSBvbmx5XCIsIHtcbiAgICAgIHB1YmxpY1BvcnQ6IHJlc29sdmVkLnB1YmxpY1BvcnQsXG4gICAgfSk7XG4gIH1cbiAgc3VwZXJ2aXNlKGNoaWxkcmVuKTtcbn1cblxuLyoqIFRoZSBgZGJ4IHR1bm5lbGAgcHJvZ3JhbS4gTm8gc2lkZSBlZmZlY3RzIHVudGlsIHBhcnNlZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFByb2dyYW0obmFtZSA9IFwiZGJ4IHR1bm5lbFwiKTogQ29tbWFuZCB7XG4gIGNvbnN0IHByb2dyYW0gPSBhZGRPcHRpb25zKFxuICAgIG5ldyBDb21tYW5kKClcbiAgICAgIC5uYW1lKG5hbWUpXG4gICAgICAuZGVzY3JpcHRpb24oXCJGcm9udCBhIGNvbW1hbmQgd2l0aCBhIHBvcnRyIHR1bm5lbCBhbmQgcGFzc3dvcmRsZXNzIGF1dGhcIiksXG4gICk7XG5cbiAgLy8gYHJ1bmAgaXMgdGhlIERFRkFVTFQgYWN0aW9uIGFzIHdlbGwgYXMgYSBuYW1lZCBzdWJjb21tYW5kLCBwcmVzZXJ2aW5nIHRoZSBvbGRcbiAgLy8gd3JhcHBlcidzIGVyZ29ub21pY3MgKGBkYnggdHVubmVsIC0tYWxsb3cgeCAtLSBidW4gc3JjL3NlcnZlci50c2ApIHdoaWxlXG4gIC8vIGxlYXZpbmcgc29tZXdoZXJlIGZvciBgc3RhdHVzYCBhbmQgYGluc3RhbGxgIHRvIGxpdmUuXG4gIHByb2dyYW1cbiAgICAuYXJndW1lbnQoXCJbY29tbWFuZC4uLl1cIiwgXCJ0aGUgY29tbWFuZCB0byB3cmFwLCBhZnRlciBgLS1gXCIpXG4gICAgLmFjdGlvbihhc3luYyAoY29tbWFuZDogc3RyaW5nW10sIF9vcHRpb25zOiBUdW5uZWxPcHRpb25zLCBjbWQ6IENvbW1hbmQpID0+IHtcbiAgICAgIGF3YWl0IHJ1bihjbWQub3B0czxUdW5uZWxPcHRpb25zPigpLCBjb21tYW5kKTtcbiAgICB9KTtcblxuICBhZGRPcHRpb25zKHByb2dyYW0uY29tbWFuZChcInJ1blwiKS5kZXNjcmlwdGlvbihcIldyYXAgYSBjb21tYW5kICh0aGUgZGVmYXVsdCBhY3Rpb24pXCIpKVxuICAgIC5hcmd1bWVudChcIjxjb21tYW5kLi4uPlwiLCBcInRoZSBjb21tYW5kIHRvIHdyYXAsIGFmdGVyIGAtLWBcIilcbiAgICAuYWN0aW9uKGFzeW5jIChjb21tYW5kOiBzdHJpbmdbXSwgX29wdGlvbnM6IFR1bm5lbE9wdGlvbnMsIGNtZDogQ29tbWFuZCkgPT4ge1xuICAgICAgYXdhaXQgcnVuKGNtZC5vcHRzPFR1bm5lbE9wdGlvbnM+KCksIGNvbW1hbmQpO1xuICAgIH0pO1xuXG4gIC8vIFdvcnRoIGl0cyBvd24gY29tbWFuZDogdGhlIG1vc3QgY29tbW9uIGZhaWx1cmUgaXMgYSB0dW5uZWwgdGhhdCBzaWxlbnRseVxuICAvLyBkb2VzIG5vdGhpbmcgYmVjYXVzZSBubyB0b2tlbiBvciBkb21haW4gcmVzb2x2ZWQsIGFuZCB0aGlzIHByaW50cyBleGFjdGx5XG4gIC8vIHdoYXQgd291bGQgaGFwcGVuIHdpdGhvdXQgc3RhcnRpbmcgYW55dGhpbmcuXG4gIGFkZE9wdGlvbnMoXG4gICAgcHJvZ3JhbS5jb21tYW5kKFwic3RhdHVzXCIpLmRlc2NyaXB0aW9uKFwiUmVzb2x2ZSB0aGUgY29uZmlndXJhdGlvbiBhbmQgcHJpbnQgaXRcIiksXG4gICkuYWN0aW9uKChfb3B0aW9uczogVHVubmVsT3B0aW9ucywgY21kOiBDb21tYW5kKSA9PiB7XG4gICAgY29uc3QgcmVzb2x2ZWQgPSByZXNvbHZlVHVubmVsT3B0aW9ucyhjbWQub3B0czxUdW5uZWxPcHRpb25zPigpKTtcbiAgICBwcm9jZXNzLnN0ZG91dC53cml0ZShgJHtKU09OLnN0cmluZ2lmeShyZXNvbHZlZCwgbnVsbCwgMil9XFxuYCk7XG4gIH0pO1xuXG4gIHByb2dyYW1cbiAgICAuY29tbWFuZChcImluc3RhbGxcIilcbiAgICAuZGVzY3JpcHRpb24oXCJJbnN0YWxsIHRoZSBwb3J0ciBiaW5hcnkgYW5kIGV4aXRcIilcbiAgICAuYWN0aW9uKGFzeW5jICgpID0+IHtcbiAgICAgIGF3YWl0IHBvcnRyLmluc3RhbGxQb3J0cigpO1xuICAgIH0pO1xuXG4gIHJldHVybiBwcm9ncmFtO1xufVxuIl19
|
|
215
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NsaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXNCRztBQUVILE9BQU8sRUFBcUIsS0FBSyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDOUQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUN4QyxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNwRCxPQUFPLEVBQUUsb0JBQW9CLEVBQXNCLE1BQU0sY0FBYyxDQUFDO0FBQ3hFLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFeEMsT0FBTyxFQUFFLGNBQWMsRUFBRSxDQUFDO0FBRTFCLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7QUFFcEMsaUZBQWlGO0FBQ2pGLE1BQU0saUJBQWlCLEdBQUcsS0FBSyxDQUFDO0FBRWhDOzs7O0dBSUc7QUFDSCxTQUFTLFFBQVE7SUFDZixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1FBQ3JDLE1BQU0sS0FBSyxHQUFHLFlBQVksRUFBRSxDQUFDO1FBQzdCLEtBQUssQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQzFCLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLFdBQVcsRUFBRSxHQUFHLEVBQUU7WUFDaEMsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2hDLE1BQU0sSUFBSSxHQUFHLE9BQU8sT0FBTyxLQUFLLFFBQVEsSUFBSSxP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QUNqRSxDQUFDLENBQUMsQ0FBQztJQUVILE9BQU87U0FDSixPQUFPLENBQUMsU0FBUyxDQUFDO1NBQ2xCLFFBQVEsQ0FBQyxhQUFhLEVBQUUscUJBQXFCLEVBQUUsT0FBTyxDQUFDO1NBQ3ZELFdBQVcsQ0FBQyxnREFBZ0QsQ0FBQztTQUM3RCxNQUFNLENBQUMsS0FBSyxFQUFFLFNBQWlCLEVBQUUsRUFBRTtRQUNsQyxJQUFJLFNBQVMsS0FBSyxPQUFPLElBQUksU0FBUyxLQUFLLE1BQU07WUFBRSxNQUFNLEtBQUssQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUM5RSxJQUFJLFNBQVMsS0FBSyxLQUFLLElBQUksU0FBUyxLQUFLLE1BQU07WUFBRSxNQUFNLEdBQUcsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUN4RSxJQUFJLFNBQVMsS0FBSyxPQUFPLElBQUksU0FBUyxLQUFLLEtBQUssSUFBSSxTQUFTLEtBQUssTUFBTSxFQUFFLENBQUM7WUFDekUsTUFBTSxJQUFJLGNBQWMsQ0FBQyxDQUFDLEVBQUUsMEJBQTBCLEVBQUUsc0JBQXNCLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDN0YsQ0FBQztJQUNILENBQUMsQ0FBQyxDQUFDO0lBRUwsT0FBTyxPQUFPLENBQUM7QUFDakIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogYGRieCB0dW5uZWxgIC0gZnJvbnQgYSBjb21tYW5kIHdpdGggYSBwdWJsaWMgcG9ydHIgdHVubmVsIGFuZCBwYXNzd29yZGxlc3MgZ2F0ZS5cbiAqXG4gKiBUaGlzIGlzIHRoZSBXUkFQUEVSIHBhdGgsIGFuZCBpdCBleGlzdHMgZm9yIG9uZSBjYXNlOiBhIHByb2plY3QgdGhhdCBkb2VzIG5vdFxuICogdXNlIGBAZGJ4LXRvb2xzL2FwcGtpdGAncyBgY3JlYXRlQXBwYCwgYW5kIHRoZXJlZm9yZSBjYW5ub3QgcmVnaXN0ZXJcbiAqIGB0dW5uZWxJbnRlcmNlcHRvcigpYCArIHRoZSBgYXV0aEdhdGVgIHBsdWdpbiBpbi1wcm9jZXNzLiBBbiBBcHBLaXQgYXBwIHNob3VsZFxuICogc3RpbGwgdGFrZSB0aGUgcGx1Z2luIHBhdGggLSBvbmUgcHJvY2Vzcywgbm8gcHJveHkgaG9wLCBubyBkdXBsaWNhdGVkIGhlYWRlclxuICogaGFuZGxpbmcuXG4gKlxuICogVGhlIHdyYXBwZXIgY2xhaW1zIHRoZSBQVUJMSUMgcG9ydCAoYERBVEFCUklDS1NfQVBQX1BPUlRgLCB0aGUgcG9ydCB0aGVcbiAqIHBsYXRmb3JtIGFuZCBwb3J0ciByb3V0ZSB0byksIG1vdmVzIHRoZSB3cmFwcGVkIGFwcCB0byBhIHByaXZhdGUgb25lLCBhbmRcbiAqIHJldmVyc2UtcHJveGllcyBiZXR3ZWVuIHRoZW0gc28gdGhlIGdhdGUgc2l0cyBpbiBmcm9udCBvZiB0cmFmZmljIGl0IHdvdWxkXG4gKiBvdGhlcndpc2UgaGF2ZSBubyB3YXkgdG8gaW50ZXJjZXB0LiBFdmVyeXRoaW5nIGVsc2UgaXMgZGVsZWdhdGVkOiB0aGUgZ2F0ZVxuICogY29uZmlnIGNvbWVzIGZyb20gYHBsdWdpbi5yZXNvbHZlQXV0aEdhdGVDb25maWdgLCB0aGUgcG9ydHIgbGlmZWN5Y2xlIGZyb21cbiAqIGBwb3J0ci4qYCAtIGJvdGggdGhlIHNhbWUgZnVuY3Rpb25zIHRoZSBpbi1wcm9jZXNzIHBhdGggdXNlcy5cbiAqXG4gKiBTaGlwcyBubyBiaW4uIGBAZGJ4LXRvb2xzL2NsaWAgbW91bnRzIGBidWlsZFByb2dyYW0oKWAgYXMgYGRieCB0dW5uZWxgIGxhemlseSxcbiAqIHNvIGBkYnggZGV2YCBwYXlzIGZvciBub25lIG9mIHRoaXMsIGFuZCBgLS1pbnNlY3VyZWAgLyBgc3RhdHVzYCAvIGBpbnN0YWxsYFxuICogbmV2ZXIgbG9hZCBBcHBLaXQgb3IgdGhlIFNNVFAgc3RhY2sgZWl0aGVyICh0aGUgZ2F0ZSBhcHAgaXMgYmVoaW5kIGEgZHluYW1pY1xuICogaW1wb3J0KS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgdHlwZSBDaGlsZFByb2Nlc3MsIHNwYXduIH0gZnJvbSBcIm5vZGU6Y2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IHsgY3JlYXRlU2VydmVyIH0gZnJvbSBcIm5vZGU6bmV0XCI7XG5pbXBvcnQgeyBsb2cgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHsgZnJwLCBwb3J0ciB9IGZyb20gXCJAZGJ4LXRvb2xzL3R1bm5lbFwiO1xuaW1wb3J0IHsgQ29tbWFuZCwgQ29tbWFuZGVyRXJyb3IgfSBmcm9tIFwiY29tbWFuZGVyXCI7XG5pbXBvcnQgeyByZXNvbHZlVHVubmVsT3B0aW9ucywgdHlwZSBUdW5uZWxPcHRpb25zIH0gZnJvbSBcIi4vb3B0aW9ucy50c1wiO1xuaW1wb3J0IHsgc3RhcnRQcm94eSB9IGZyb20gXCIuL3Byb3h5LnRzXCI7XG5cbmV4cG9ydCB7IENvbW1hbmRlckVycm9yIH07XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJ0dW5uZWxcIik7XG5cbi8qKiBIb3cgbG9uZyBhIGNoaWxkIGdldHMgdG8gZXhpdCBvbiBTSUdURVJNIGJlZm9yZSB0aGUgd3JhcHBlciBsZWF2ZXMgYW55d2F5LiAqL1xuY29uc3QgU0hVVERPV05fR1JBQ0VfTVMgPSAzXzAwMDtcblxuLyoqXG4gKiBBIGZyZWUgbG9vcGJhY2sgcG9ydCwgZnJvbSB0aGUgT1MgcmF0aGVyIHRoYW4gYSByYW5kb20gZ3Vlc3M6IGJpbmRpbmcgYDBgIGFuZFxuICogcmVhZGluZyBiYWNrIHdoYXQgd2FzIGFzc2lnbmVkIGlzIHRoZSBvbmx5IHdheSB0byBrbm93IHRoZSBwb3J0IGlzIGFjdHVhbGx5XG4gKiBhdmFpbGFibGUsIHNvIHR3byB0dW5uZWxzIGNhbiBydW4gc2lkZSBieSBzaWRlIHdpdGhvdXQgY29sbGlkaW5nLlxuICovXG5mdW5jdGlvbiBmcmVlUG9ydCgpOiBQcm9taXNlPG51bWJlcj4ge1xuICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIGNvbnN0IHByb2JlID0gY3JlYXRlU2VydmVyKCk7XG4gICAgcHJvYmUub24oXCJlcnJvclwiLCByZWplY3QpO1xuICAgIHByb2JlLmxpc3RlbigwLCBcIjEyNy4wLjAuMVwiLCAoKSA9PiB7XG4gICAgICBjb25zdCBhZGRyZXNzID0gcHJvYmUuYWRkcmVzcygpO1xuICAgICAgY29uc3QgcG9ydCA9IHR5cGVvZiBhZGRyZXNzID09PSBcIm9iamVjdFwiICYmIGFkZHJlc3MgPyBhZGRyZXNzLnBvcnQgOiAwO1xuICAgICAgcHJvYmUuY2xvc2UoKCkgPT4gKHBvcnQgPiAwID8gcmVzb2x2ZShwb3J0KSA6IHJlamVjdChuZXcgRXJyb3IoXCJubyBmcmVlIHBvcnRcIikpKSk7XG4gICAgfSk7XG4gIH0pO1xufVxuXG4vKipcbiAqIEV2ZXJ5IGdhdGUvcG9ydHIgZmxhZy4gRGVjbGFyZWQgb24gdGhlIHJvb3QgY29tbWFuZCBBTkQgb24gYHJ1bmAvYHN0YXR1c2Agc29cbiAqIGBkYnggdHVubmVsIC0tYWxsb3cgeCAtLSBjbWRgIGFuZCBgZGJ4IHR1bm5lbCBydW4gLS1hbGxvdyB4IC0tIGNtZGAgYmVoYXZlXG4gKiBpZGVudGljYWxseSAtIGNvbW1hbmRlciBkb2VzIG5vdCBpbmhlcml0IG9wdGlvbnMgZG93bndhcmQuXG4gKi9cbmZ1bmN0aW9uIGFkZE9wdGlvbnMoY29tbWFuZDogQ29tbWFuZCk6IENvbW1hbmQge1xuICByZXR1cm4gY29tbWFuZFxuICAgIC5vcHRpb24oXCItLXRyYW5zcG9ydCA8dHJhbnNwb3J0PlwiLCBcInB1YmxpYyB0dW5uZWwgdHJhbnNwb3J0OiBwb3J0ciwgZnJwLCBvciBib3RoXCIpXG4gICAgLm9wdGlvbihcIi0tcHVibGljLWRvbWFpbiA8aG9zdD5cIiwgXCJwdWJsaWMgdHVubmVsIGRvbWFpblwiKVxuICAgIC5vcHRpb24oXCItLXN1YmRvbWFpbiA8bmFtZT5cIiwgXCJwb3J0ciBzdWJkb21haW4gKGVsc2UgZGVyaXZlZCBmcm9tIHRoZSBwdWJsaWMgZG9tYWluKVwiKVxuICAgIC5vcHRpb24oXCItLXBvcnQgPHBvcnQ+XCIsIFwicHVibGljIHBvcnQgdGhlIHdyYXBwZXIgbGlzdGVucyBvblwiKVxuICAgIC5vcHRpb24oXCItLWFwcC1wb3J0IDxwb3J0PlwiLCBcInByaXZhdGUgcG9ydCB0aGUgd3JhcHBlZCBhcHAgaXMgdG9sZCB0byBiaW5kXCIpXG4gICAgLm9wdGlvbihcIi0tYWxsb3cgPHBhdHRlcm5zLi4uPlwiLCBcImVtYWlsIGFsbG93LWxpc3QgKGRvbWFpbiAvIGdsb2IgLyAvcmVnZXgvKVwiKVxuICAgIC5vcHRpb24oXCItLXN1YmplY3QgPHRleHQ+XCIsIFwidmVyaWZpY2F0aW9uIGVtYWlsIHN1YmplY3RcIilcbiAgICAub3B0aW9uKFwiLS1icmFuZC1uYW1lIDxuYW1lPlwiLCBcInZlcmlmaWNhdGlvbiBlbWFpbCBicmFuZCBuYW1lXCIpXG4gICAgLm9wdGlvbihcIi0tbWVzc2FnZSA8dGV4dD5cIiwgXCJ2ZXJpZmljYXRpb24gZW1haWwgbWVzc2FnZVwiKVxuICAgIC5vcHRpb24oXCItLXNlc3Npb24tdHRsIDxzZWNvbmRzPlwiLCBcInNlc3Npb24gbGlmZXRpbWVcIilcbiAgICAub3B0aW9uKFwiLS1jb2RlLXR0bCA8c2Vjb25kcz5cIiwgXCJvbmUtdGltZS1jb2RlIGxpZmV0aW1lXCIpXG4gICAgLm9wdGlvbihcIi0tc2Vzc2lvbi1jdXRvZmYgPHdoZW4+XCIsIFwiaW52YWxpZGF0ZSBldmVyeSBzZXNzaW9uIGlzc3VlZCBiZWZvcmUgdGhpc1wiKVxuICAgIC5vcHRpb24oXCItLWF1dGgtc3RvcmFnZSA8bW9kZT5cIiwgXCJhdXRoIGRhdGFiYXNlOiBhdXRvLCBsYWtlYmFzZSwgb3Igc3FsaXRlXCIpXG4gICAgLm9wdGlvbihcIi0tYXV0aC1zcWxpdGUtcGF0aCA8cGF0aD5cIiwgXCJsb2NhbCBCZXR0ZXIgQXV0aCBTUUxpdGUgZmlsZVwiKVxuICAgIC5vcHRpb24oXCItLWZvcndhcmQtaGVhZGVycyA8cGF0dGVybnMuLi4+XCIsIFwiZXh0cmEgeC0gaGVhZGVycyB0dW5uZWwgdHJhZmZpYyBtYXkgZm9yd2FyZFwiKVxuICAgIC5vcHRpb24oXCItLWdhdGUtcGF0aCA8cHJlZml4Li4uPlwiLCBcInBhdGggcHJlZml4ZXMgdG8gZ2F0ZSBiZXlvbmQgL2FwaS8gKGUuZy4gL3dzKVwiKVxuICAgIC5vcHRpb24oXCItLWJpbmQgPGhvc3QuLi4+XCIsIFwiaW50ZXJmYWNlIElQcyB0aGUgZ2F0ZSBsaXN0ZW5zIG9uIChkZWZhdWx0OiAwLjAuMC4wKVwiKVxuICAgIC5vcHRpb24oXCItLWZycC1zZXJ2ZXIgPGhvc3Q+XCIsIFwiZnJwcyBjb250cm9sIGhvc3QgKGRlZmF1bHQ6IEZSUCBwdWJsaWMgZG9tYWluKVwiKVxuICAgIC5vcHRpb24oXCItLWZycC1wdWJsaWMtZG9tYWluIDxob3N0PlwiLCBcIkZSUCBwdWJsaWMgSFRUUCBkb21haW5cIilcbiAgICAub3B0aW9uKFwiLS1mcnAtc2VydmVyLXBvcnQgPHBvcnQ+XCIsIFwiZnJwcyBjb250cm9sIHBvcnQgKGRlZmF1bHQ6IDQ0MylcIilcbiAgICAub3B0aW9uKFwiLS1mcnAtcHJvdG9jb2wgPHByb3RvY29sPlwiLCBcImZycGMgdHJhbnNwb3J0IHByb3RvY29sIChkZWZhdWx0OiB3c3MpXCIpXG4gICAgLm9wdGlvbihcIi0tZnJwLXRva2VuIDx0b2tlbj5cIiwgXCJmcnBzIGF1dGggdG9rZW5cIilcbiAgICAub3B0aW9uKFwiLS1mcnAtcHJveHktbmFtZSA8bmFtZT5cIiwgXCJmcnAgcHJveHkgcmVnaXN0cmF0aW9uIG5hbWVcIilcbiAgICAub3B0aW9uKFwiLS1pbnNlY3VyZVwiLCBcInJ1biBvcGVuLCB3aXRoIG5vIGdhdGVcIik7XG59XG5cbi8qKlxuICogVGllIHRoZSB3cmFwcGVyJ3MgbGlmZXRpbWUgdG8gaXRzIGNoaWxkcmVuJ3MsIGluIGJvdGggZGlyZWN0aW9uczogYSBjaGlsZCB0aGF0XG4gKiBleGl0cyB0YWtlcyB0aGUgd3JhcHBlciBkb3duIHdpdGggaXRzIGNvZGUsIGFuZCBhIHNpZ25hbCB0byB0aGUgd3JhcHBlciBpc1xuICogZm9yd2FyZGVkIGJlZm9yZSBpdCBsZWF2ZXMuIFdpdGhvdXQgdGhpcyBhIGNyYXNoZWQgYXBwIGxlYXZlcyBhIHBvcnRyIHR1bm5lbFxuICogc2VydmluZyBhIGRlYWQgcG9ydCwgd2hpY2ggbG9va3MgbGlrZSBhIGhhbmcgcmF0aGVyIHRoYW4gYSBmYWlsdXJlLlxuICovXG5mdW5jdGlvbiBzdXBlcnZpc2UoY2hpbGRyZW46IHJlYWRvbmx5IENoaWxkUHJvY2Vzc1tdKTogdm9pZCB7XG4gIGxldCBzdG9wcGluZyA9IGZhbHNlO1xuICBjb25zdCBzdG9wID0gKGNvZGU6IG51bWJlcik6IHZvaWQgPT4ge1xuICAgIGlmIChzdG9wcGluZykgcmV0dXJuO1xuICAgIHN0b3BwaW5nID0gdHJ1ZTtcbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIGNoaWxkcmVuKSBpZiAoIWNoaWxkLmtpbGxlZCkgY2hpbGQua2lsbChcIlNJR1RFUk1cIik7XG4gICAgc2V0VGltZW91dCgoKSA9PiBwcm9jZXNzLmV4aXQoY29kZSksIFNIVVRET1dOX0dSQUNFX01TKS51bnJlZigpO1xuICB9O1xuICBmb3IgKGNvbnN0IGNoaWxkIG9mIGNoaWxkcmVuKSBjaGlsZC5vbihcImV4aXRcIiwgKGNvZGUpID0+IHN0b3AoY29kZSA/PyAxKSk7XG4gIGZvciAoY29uc3Qgc2lnbmFsIG9mIFtcIlNJR1RFUk1cIiwgXCJTSUdJTlRcIiwgXCJTSUdIVVBcIl0gYXMgY29uc3QpIHtcbiAgICBwcm9jZXNzLm9uKHNpZ25hbCwgKCkgPT4gc3RvcCgwKSk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gcnVuKHJhdzogVHVubmVsT3B0aW9ucywgY29tbWFuZDogcmVhZG9ubHkgc3RyaW5nW10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgW2V4ZWN1dGFibGUsIC4uLmFyZ3NdID0gY29tbWFuZDtcbiAgY29uc3QgcmVzb2x2ZWQgPSByZXNvbHZlVHVubmVsT3B0aW9ucyhyYXcpO1xuICBjb25zdCBjaGlsZHJlbjogQ2hpbGRQcm9jZXNzW10gPSBbXTtcblxuICAvLyBUd28gdXBzdHJlYW0gbW9kZXM6XG4gIC8vICAgLSBXUkFQOiBhIGNvbW1hbmQgYWZ0ZXIgYC0tYC4gVGhlIHdyYXBwZXIgc3Bhd25zIGl0IG9uIGEgcHJpdmF0ZSBsb29wYmFja1xuICAvLyAgICAgcG9ydCBhbmQgaXMgdGhlIG9ubHkgdGhpbmcgdGhhdCB0YWxrcyB0byBpdC5cbiAgLy8gICAtIEFUVEFDSDogbm8gY29tbWFuZCwgYnV0IGAtLWFwcC1wb3J0YCBuYW1lcyBhbiBhbHJlYWR5LXJ1bm5pbmcgdXBzdHJlYW1cbiAgLy8gICAgIChlLmcuIGEgbG9jYWwgcmV2ZXJzZSBwcm94eSkuIFRoZSBnYXRlIGZyb250cyBpdCB3aXRob3V0IHNwYXduaW5nIGFcbiAgLy8gICAgIGNoaWxkLiBUaGlzIGlzIHdoYXQgbGV0cyB0aGUgZ2F0ZSBzaXQgb24gYW4gaW50ZXJmYWNlIGluIGZyb250IG9mIGFcbiAgLy8gICAgIHNlcGFyYXRlbHktc3VwZXJ2aXNlZCBzdGFjay5cbiAgbGV0IGFwcFBvcnQ6IG51bWJlcjtcbiAgaWYgKGV4ZWN1dGFibGUpIHtcbiAgICBhcHBQb3J0ID0gcmVzb2x2ZWQuYXBwUG9ydCA/PyAoYXdhaXQgZnJlZVBvcnQoKSk7XG4gICAgY29uc3QgYXBwID0gc3Bhd24oZXhlY3V0YWJsZSwgYXJncywge1xuICAgICAgZW52OiB7XG4gICAgICAgIC4uLnByb2Nlc3MuZW52LFxuICAgICAgICBEQVRBQlJJQ0tTX0FQUF9QT1JUOiBTdHJpbmcoYXBwUG9ydCksXG4gICAgICAgIFBPUlQ6IFN0cmluZyhhcHBQb3J0KSxcbiAgICAgICAgSE9TVDogXCIxMjcuMC4wLjFcIixcbiAgICAgIH0sXG4gICAgICBzdGRpbzogXCJpbmhlcml0XCIsXG4gICAgfSk7XG4gICAgY2hpbGRyZW4ucHVzaChhcHApO1xuICB9IGVsc2UgaWYgKHJlc29sdmVkLmFwcFBvcnQpIHtcbiAgICBhcHBQb3J0ID0gcmVzb2x2ZWQuYXBwUG9ydDtcbiAgICBsb2dnZXIuaW5mbyhcImF0dGFjaGluZyBnYXRlIHRvIGV4aXN0aW5nIHVwc3RyZWFtXCIsIHsgYXBwUG9ydCB9KTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBuZXcgQ29tbWFuZGVyRXJyb3IoXG4gICAgICAxLFxuICAgICAgXCJ0dW5uZWwubm8tdXBzdHJlYW1cIixcbiAgICAgIFwibm8gY29tbWFuZCBnaXZlbiAocGFzcyBpdCBhZnRlciBgLS1gKSBhbmQgbm8gLS1hcHAtcG9ydCB0byBhdHRhY2ggdG9cIixcbiAgICApO1xuICB9XG5cbiAgLy8gRHluYW1pYyBpbXBvcnQ6IHRoZSBnYXRlIGlzIHRoZSBvbmx5IHRoaW5nIGhlcmUgdGhhdCBuZWVkcyBBcHBLaXQgKyBTTVRQLCBzb1xuICAvLyBhbiBgLS1pbnNlY3VyZWAgcnVuIG5ldmVyIGxvYWRzIGVpdGhlci5cbiAgY29uc3QgZ2F0ZSA9IHJlc29sdmVkLmdhdGUuaW5zZWN1cmVcbiAgICA/IHVuZGVmaW5lZFxuICAgIDogYXdhaXQgKFxuICAgICAgICBhd2FpdCBpbXBvcnQoXCIuL2FwcC50c1wiKVxuICAgICAgKS5zdGFydEdhdGVBcHAoe1xuICAgICAgICAuLi5yZXNvbHZlZC5nYXRlQ29uZmlnLFxuICAgICAgICBwdWJsaWNEb21haW46IHJlc29sdmVkLmdhdGUucHVibGljRG9tYWluID8/IGBsb2NhbGhvc3Q6JHtyZXNvbHZlZC5wdWJsaWNQb3J0fWAsXG4gICAgICB9KTtcbiAgaWYgKCFnYXRlKSBsb2dnZXIud2FybihcInJ1bm5pbmcgT1BFTiAtIG5vIGdhdGUgaXMgaW4gZnJvbnQgb2YgdGhpcyB0dW5uZWxcIik7XG5cbiAgYXdhaXQgc3RhcnRQcm94eSh7XG4gICAgcHVibGljUG9ydDogcmVzb2x2ZWQucHVibGljUG9ydCxcbiAgICBhcHBQb3J0LFxuICAgIGdhdGUsXG4gICAgZm9yd2FyZEhlYWRlcnM6IHJlc29sdmVkLmdhdGUuZm9yd2FyZEhlYWRlcnMsXG4gICAgZ2F0ZVBhdGhzOiByZXNvbHZlZC5nYXRlLmdhdGVQYXRocyxcbiAgICBicmFuZE5hbWU6IHJlc29sdmVkLmdhdGUuYnJhbmROYW1lLFxuICAgIGJpbmRIb3N0czogcmVzb2x2ZWQuYmluZEhvc3RzLFxuICB9KTtcblxuICBpZiAoKHJlc29sdmVkLnRyYW5zcG9ydCA9PT0gXCJwb3J0clwiIHx8IHJlc29sdmVkLnRyYW5zcG9ydCA9PT0gXCJib3RoXCIpICYmIHJlc29sdmVkLnBvcnRyKSB7XG4gICAgY29uc3QgcG9ydHJFbnYgPSBhd2FpdCBwb3J0ci5pbnN0YWxsUG9ydHIoKTtcbiAgICBhd2FpdCBwb3J0ci53cml0ZVBvcnRyQ29uZmlnKHJlc29sdmVkLnBvcnRyLCBwb3J0ckVudik7XG4gICAgY2hpbGRyZW4ucHVzaChhd2FpdCBwb3J0ci5zdGFydFBvcnRyKHJlc29sdmVkLnBvcnRyLCBwb3J0ckVudikpO1xuICB9XG4gIGlmICgocmVzb2x2ZWQudHJhbnNwb3J0ID09PSBcImZycFwiIHx8IHJlc29sdmVkLnRyYW5zcG9ydCA9PT0gXCJib3RoXCIpICYmIHJlc29sdmVkLmZycCkge1xuICAgIGNvbnN0IGZycEVudiA9IGF3YWl0IGZycC5pbnN0YWxsRnJwKCk7XG4gICAgY29uc3QgY29uZmlnUGF0aCA9IGF3YWl0IGZycC53cml0ZUZycENvbmZpZyhyZXNvbHZlZC5mcnAsIGZycEVudik7XG4gICAgY2hpbGRyZW4ucHVzaChmcnAuc3RhcnRGcnAocmVzb2x2ZWQuZnJwLCBmcnBFbnYsIGNvbmZpZ1BhdGgpKTtcbiAgfVxuICBjb25zdCBhY3RpdmVUdW5uZWxDb3VudCA9IGNoaWxkcmVuLmxlbmd0aCAtIChleGVjdXRhYmxlID8gMSA6IDApO1xuICBpZiAoIWFjdGl2ZVR1bm5lbENvdW50KSBsb2dnZXIuaW5mbyhcIm5vIHNlbGVjdGVkIHB1YmxpYyB0dW5uZWwgaXMgY29uZmlndXJlZFwiLCB7XG4gICAgdHJhbnNwb3J0OiByZXNvbHZlZC50cmFuc3BvcnQsXG4gICAgcHVibGljUG9ydDogcmVzb2x2ZWQucHVibGljUG9ydCxcbiAgfSk7XG4gIHN1cGVydmlzZShjaGlsZHJlbik7XG59XG5cbi8qKiBUaGUgYGRieCB0dW5uZWxgIHByb2dyYW0uIE5vIHNpZGUgZWZmZWN0cyB1bnRpbCBwYXJzZWQuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRQcm9ncmFtKG5hbWUgPSBcImRieCB0dW5uZWxcIik6IENvbW1hbmQge1xuICBjb25zdCBwcm9ncmFtID0gYWRkT3B0aW9ucyhcbiAgICBuZXcgQ29tbWFuZCgpXG4gICAgICAubmFtZShuYW1lKVxuICAgICAgLmRlc2NyaXB0aW9uKFwiRnJvbnQgYSBjb21tYW5kIHdpdGggYSBwdWJsaWMgdHVubmVsIGFuZCBwYXNzd29yZGxlc3MgYXV0aFwiKSxcbiAgKTtcblxuICAvLyBgcnVuYCBpcyB0aGUgREVGQVVMVCBhY3Rpb24gYXMgd2VsbCBhcyBhIG5hbWVkIHN1YmNvbW1hbmQsIHByZXNlcnZpbmcgdGhlIG9sZFxuICAvLyB3cmFwcGVyJ3MgZXJnb25vbWljcyAoYGRieCB0dW5uZWwgLS1hbGxvdyB4IC0tIGJ1biBzcmMvc2VydmVyLnRzYCkgd2hpbGVcbiAgLy8gbGVhdmluZyBzb21ld2hlcmUgZm9yIGBzdGF0dXNgIGFuZCBgaW5zdGFsbGAgdG8gbGl2ZS5cbiAgcHJvZ3JhbVxuICAgIC5hcmd1bWVudChcIltjb21tYW5kLi4uXVwiLCBcInRoZSBjb21tYW5kIHRvIHdyYXAsIGFmdGVyIGAtLWBcIilcbiAgICAuYWN0aW9uKGFzeW5jIChjb21tYW5kOiBzdHJpbmdbXSwgX29wdGlvbnM6IFR1bm5lbE9wdGlvbnMsIGNtZDogQ29tbWFuZCkgPT4ge1xuICAgICAgYXdhaXQgcnVuKGNtZC5vcHRzPFR1bm5lbE9wdGlvbnM+KCksIGNvbW1hbmQpO1xuICAgIH0pO1xuXG4gIGFkZE9wdGlvbnMocHJvZ3JhbS5jb21tYW5kKFwicnVuXCIpLmRlc2NyaXB0aW9uKFwiV3JhcCBhIGNvbW1hbmQgKHRoZSBkZWZhdWx0IGFjdGlvbilcIikpXG4gICAgLmFyZ3VtZW50KFwiPGNvbW1hbmQuLi4+XCIsIFwidGhlIGNvbW1hbmQgdG8gd3JhcCwgYWZ0ZXIgYC0tYFwiKVxuICAgIC5hY3Rpb24oYXN5bmMgKGNvbW1hbmQ6IHN0cmluZ1tdLCBfb3B0aW9uczogVHVubmVsT3B0aW9ucywgY21kOiBDb21tYW5kKSA9PiB7XG4gICAgICBhd2FpdCBydW4oY21kLm9wdHM8VHVubmVsT3B0aW9ucz4oKSwgY29tbWFuZCk7XG4gICAgfSk7XG5cbiAgLy8gV29ydGggaXRzIG93biBjb21tYW5kOiB0aGUgbW9zdCBjb21tb24gZmFpbHVyZSBpcyBhIHR1bm5lbCB0aGF0IHNpbGVudGx5XG4gIC8vIGRvZXMgbm90aGluZyBiZWNhdXNlIG5vIHRva2VuIG9yIGRvbWFpbiByZXNvbHZlZCwgYW5kIHRoaXMgcHJpbnRzIGV4YWN0bHlcbiAgLy8gd2hhdCB3b3VsZCBoYXBwZW4gd2l0aG91dCBzdGFydGluZyBhbnl0aGluZy5cbiAgYWRkT3B0aW9ucyhcbiAgICBwcm9ncmFtLmNvbW1hbmQoXCJzdGF0dXNcIikuZGVzY3JpcHRpb24oXCJSZXNvbHZlIHRoZSBjb25maWd1cmF0aW9uIGFuZCBwcmludCBpdFwiKSxcbiAgKS5hY3Rpb24oKF9vcHRpb25zOiBUdW5uZWxPcHRpb25zLCBjbWQ6IENvbW1hbmQpID0+IHtcbiAgICBjb25zdCByZXNvbHZlZCA9IHJlc29sdmVUdW5uZWxPcHRpb25zKGNtZC5vcHRzPFR1bm5lbE9wdGlvbnM+KCkpO1xuICAgIHByb2Nlc3Muc3Rkb3V0LndyaXRlKGAke0pTT04uc3RyaW5naWZ5KHJlc29sdmVkLCBudWxsLCAyKX1cXG5gKTtcbiAgfSk7XG5cbiAgcHJvZ3JhbVxuICAgIC5jb21tYW5kKFwiaW5zdGFsbFwiKVxuICAgIC5hcmd1bWVudChcIlt0cmFuc3BvcnRdXCIsIFwicG9ydHIsIGZycCwgb3IgYm90aFwiLCBcInBvcnRyXCIpXG4gICAgLmRlc2NyaXB0aW9uKFwiSW5zdGFsbCBwdWJsaWMgdHVubmVsIGNsaWVudCBiaW5hcmllcyBhbmQgZXhpdFwiKVxuICAgIC5hY3Rpb24oYXN5bmMgKHRyYW5zcG9ydDogc3RyaW5nKSA9PiB7XG4gICAgICBpZiAodHJhbnNwb3J0ID09PSBcInBvcnRyXCIgfHwgdHJhbnNwb3J0ID09PSBcImJvdGhcIikgYXdhaXQgcG9ydHIuaW5zdGFsbFBvcnRyKCk7XG4gICAgICBpZiAodHJhbnNwb3J0ID09PSBcImZycFwiIHx8IHRyYW5zcG9ydCA9PT0gXCJib3RoXCIpIGF3YWl0IGZycC5pbnN0YWxsRnJwKCk7XG4gICAgICBpZiAodHJhbnNwb3J0ICE9PSBcInBvcnRyXCIgJiYgdHJhbnNwb3J0ICE9PSBcImZycFwiICYmIHRyYW5zcG9ydCAhPT0gXCJib3RoXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IENvbW1hbmRlckVycm9yKDEsIFwidHVubmVsLmludmFsaWQtdHJhbnNwb3J0XCIsIGBpbnZhbGlkIHRyYW5zcG9ydDogJHt0cmFuc3BvcnR9YCk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgcmV0dXJuIHByb2dyYW07XG59XG4iXX0=
|
package/lib/src/options.d.ts
CHANGED
|
@@ -12,9 +12,10 @@
|
|
|
12
12
|
* @module
|
|
13
13
|
*/
|
|
14
14
|
import type { AuthStorageMode } from "@dbx-tools/auth";
|
|
15
|
-
import { type AuthGateConfig, plugin, portr } from "@dbx-tools/tunnel";
|
|
15
|
+
import { type AuthGateConfig, frp, interceptor, plugin, portr } from "@dbx-tools/tunnel";
|
|
16
16
|
/** Raw commander flag values (every numeric flag arrives as a string). */
|
|
17
17
|
export interface TunnelOptions {
|
|
18
|
+
transport?: interceptor.TunnelTransport;
|
|
18
19
|
publicDomain?: string;
|
|
19
20
|
subdomain?: string;
|
|
20
21
|
port?: string | number;
|
|
@@ -32,6 +33,12 @@ export interface TunnelOptions {
|
|
|
32
33
|
gatePath?: string[];
|
|
33
34
|
bind?: string[];
|
|
34
35
|
insecure?: boolean;
|
|
36
|
+
frpServer?: string;
|
|
37
|
+
frpPublicDomain?: string;
|
|
38
|
+
frpServerPort?: string | number;
|
|
39
|
+
frpProtocol?: string;
|
|
40
|
+
frpToken?: string;
|
|
41
|
+
frpProxyName?: string;
|
|
35
42
|
}
|
|
36
43
|
export interface ResolvedTunnelOptions {
|
|
37
44
|
/** The port the wrapper itself listens on - what portr forwards to. */
|
|
@@ -40,6 +47,7 @@ export interface ResolvedTunnelOptions {
|
|
|
40
47
|
appPort?: number;
|
|
41
48
|
/** Interface IPs the gate listens on. Empty means the default (0.0.0.0). */
|
|
42
49
|
bindHosts: string[];
|
|
50
|
+
transport: interceptor.TunnelTransport;
|
|
43
51
|
/**
|
|
44
52
|
* The gate config as the `authGate` PLUGIN takes it - flags only, nothing
|
|
45
53
|
* resolved. Passed straight to the plugin so it applies its own fallbacks
|
|
@@ -49,5 +57,6 @@ export interface ResolvedTunnelOptions {
|
|
|
49
57
|
/** The same config after the plugin's resolution, for `status` and for routing. */
|
|
50
58
|
gate: plugin.ResolvedAuthGateConfig;
|
|
51
59
|
portr: ReturnType<typeof portr.resolvePortrConfig>;
|
|
60
|
+
frp: ReturnType<typeof frp.resolveFrpConfig>;
|
|
52
61
|
}
|
|
53
62
|
export declare function resolveTunnelOptions(options: TunnelOptions): ResolvedTunnelOptions;
|
package/lib/src/options.js
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
import { config } from "@dbx-tools/core";
|
|
15
15
|
import { object } from "@dbx-tools/shared-core";
|
|
16
|
-
import { plugin, portr } from "@dbx-tools/tunnel";
|
|
16
|
+
import { frp, interceptor, plugin, portr } from "@dbx-tools/tunnel";
|
|
17
17
|
export function resolveTunnelOptions(options) {
|
|
18
18
|
// The Databricks Apps runtime contract: the platform routes to
|
|
19
19
|
// DATABRICKS_APP_PORT, so the WRAPPER claims it and the wrapped app is moved
|
|
@@ -37,12 +37,15 @@ export function resolveTunnelOptions(options) {
|
|
|
37
37
|
gatePaths: options.gatePath,
|
|
38
38
|
insecure: options.insecure,
|
|
39
39
|
publicDomain: options.publicDomain,
|
|
40
|
+
publicDomains: options.frpPublicDomain ? [options.frpPublicDomain] : undefined,
|
|
40
41
|
};
|
|
41
42
|
const gate = plugin.resolveAuthGateConfig(gateConfig);
|
|
43
|
+
const transport = interceptor.resolveTunnelTransport(options.transport);
|
|
42
44
|
return {
|
|
43
45
|
publicPort,
|
|
44
46
|
...(appPort > 0 ? { appPort } : {}),
|
|
45
47
|
bindHosts: options.bind ?? [],
|
|
48
|
+
transport,
|
|
46
49
|
gateConfig,
|
|
47
50
|
gate,
|
|
48
51
|
portr: portr.resolvePortrConfig({
|
|
@@ -50,6 +53,15 @@ export function resolveTunnelOptions(options) {
|
|
|
50
53
|
subdomain: options.subdomain,
|
|
51
54
|
port: publicPort,
|
|
52
55
|
}),
|
|
56
|
+
frp: frp.resolveFrpConfig({
|
|
57
|
+
publicDomain: options.frpPublicDomain,
|
|
58
|
+
server: options.frpServer,
|
|
59
|
+
serverPort: options.frpServerPort,
|
|
60
|
+
protocol: options.frpProtocol,
|
|
61
|
+
token: options.frpToken,
|
|
62
|
+
proxyName: options.frpProxyName,
|
|
63
|
+
port: publicPort,
|
|
64
|
+
}),
|
|
53
65
|
};
|
|
54
66
|
}
|
|
55
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
67
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9vcHRpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7R0FZRztBQUdILE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDaEQsT0FBTyxFQUF1QixHQUFHLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQWtEekYsTUFBTSxVQUFVLG9CQUFvQixDQUFDLE9BQXNCO0lBQ3pELCtEQUErRDtJQUMvRCw2RUFBNkU7SUFDN0Usb0JBQW9CO0lBQ3BCLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxxQkFBcUIsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUMxRSxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsVUFBVSxFQUFFLENBQUMsRUFBRSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBQ2xGLE1BQU0sVUFBVSxHQUFtQjtRQUNqQyxLQUFLLEVBQUUsT0FBTyxDQUFDLEtBQUs7UUFDcEIsT0FBTyxFQUFFLE9BQU8sQ0FBQyxPQUFPO1FBQ3hCLFNBQVMsRUFBRSxPQUFPLENBQUMsU0FBUztRQUM1QixPQUFPLEVBQUUsT0FBTyxDQUFDLE9BQU87UUFDeEIsMEVBQTBFO1FBQzFFLDRFQUE0RTtRQUM1RSxrREFBa0Q7UUFDbEQsaUJBQWlCLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDO1FBQ3RELGNBQWMsRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUM7UUFDaEQsYUFBYSxFQUFFLE9BQU8sQ0FBQyxhQUFhO1FBQ3BDLE9BQU8sRUFBRSxPQUFPLENBQUMsV0FBVztRQUM1QixVQUFVLEVBQUUsT0FBTyxDQUFDLGNBQWM7UUFDbEMsY0FBYyxFQUFFLE9BQU8sQ0FBQyxjQUFjO1FBQ3RDLFNBQVMsRUFBRSxPQUFPLENBQUMsUUFBUTtRQUMzQixRQUFRLEVBQUUsT0FBTyxDQUFDLFFBQVE7UUFDMUIsWUFBWSxFQUFFLE9BQU8sQ0FBQyxZQUFZO1FBQ2xDLGFBQWEsRUFBRSxPQUFPLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUztLQUMvRSxDQUFDO0lBQ0YsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLHFCQUFxQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3RELE1BQU0sU0FBUyxHQUFHLFdBQVcsQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDeEUsT0FBTztRQUNMLFVBQVU7UUFDVixHQUFHLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ25DLFNBQVMsRUFBRSxPQUFPLENBQUMsSUFBSSxJQUFJLEVBQUU7UUFDN0IsU0FBUztRQUNULFVBQVU7UUFDVixJQUFJO1FBQ0osS0FBSyxFQUFFLEtBQUssQ0FBQyxrQkFBa0IsQ0FBQztZQUM5QixZQUFZLEVBQUUsSUFBSSxDQUFDLFlBQVk7WUFDL0IsU0FBUyxFQUFFLE9BQU8sQ0FBQyxTQUFTO1lBQzVCLElBQUksRUFBRSxVQUFVO1NBQ2pCLENBQUM7UUFDRixHQUFHLEVBQUUsR0FBRyxDQUFDLGdCQUFnQixDQUFDO1lBQ3hCLFlBQVksRUFBRSxPQUFPLENBQUMsZUFBZTtZQUNyQyxNQUFNLEVBQUUsT0FBTyxDQUFDLFNBQVM7WUFDekIsVUFBVSxFQUFFLE9BQU8sQ0FBQyxhQUFhO1lBQ2pDLFFBQVEsRUFBRSxPQUFPLENBQUMsV0FBVztZQUM3QixLQUFLLEVBQUUsT0FBTyxDQUFDLFFBQVE7WUFDdkIsU0FBUyxFQUFFLE9BQU8sQ0FBQyxZQUFZO1lBQy9CLElBQUksRUFBRSxVQUFVO1NBQ2pCLENBQUM7S0FDSCxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRmxhZyAtPiBjb25maWcgLT4gZGVmYXVsdCByZXNvbHV0aW9uIGZvciBgZGJ4IHR1bm5lbGAuXG4gKlxuICogVGhlIHBvaW50IG9mIHRoaXMgbW9kdWxlIGlzIHRoYXQgaXQgZG9lcyBhbG1vc3QgTk9USElORyBpdHNlbGY6IGV2ZXJ5IGdhdGVcbiAqIHNldHRpbmcgaXMgaGFuZGVkIHN0cmFpZ2h0IHRvIGBAZGJ4LXRvb2xzL3R1bm5lbGAncyBvd25cbiAqIGBwbHVnaW4ucmVzb2x2ZUF1dGhHYXRlQ29uZmlnYCwgd2hpY2ggaXMgdGhlIHNhbWUgZnVuY3Rpb24gdGhlIGluLXByb2Nlc3NcbiAqIHBsdWdpbiBwYXRoIGNhbGxzLiBUaGUgQ0xJIHRoZXJlZm9yZSBjYW5ub3QgZHJpZnQgZnJvbSB0aGUgcGx1Z2luIG9uIGEgZGVmYXVsdCxcbiAqIGFuIGVudiBuYW1lLCBvciBhIGNvZXJjaW9uIHJ1bGUgLSBhIGZsYWcgaXMganVzdCBhIHZhbHVlIHBhc3NlZCB3aGVyZSB0aGVcbiAqIHBsdWdpbidzIGBjb25maWdgIG9iamVjdCB3b3VsZCBnbywgYW5kIGBjb25maWcuKmAgZmlsbHMgdGhlIHJlc3QgaW4gZnJvbSB0aGVcbiAqIGVudmlyb25tZW50LCBhIGAuZW52YCBmaWxlLCBvciBgZGF0YWJyaWNrcy55bWxgLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IEF1dGhTdG9yYWdlTW9kZSB9IGZyb20gXCJAZGJ4LXRvb2xzL2F1dGhcIjtcbmltcG9ydCB7IGNvbmZpZyB9IGZyb20gXCJAZGJ4LXRvb2xzL2NvcmVcIjtcbmltcG9ydCB7IG9iamVjdCB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgeyB0eXBlIEF1dGhHYXRlQ29uZmlnLCBmcnAsIGludGVyY2VwdG9yLCBwbHVnaW4sIHBvcnRyIH0gZnJvbSBcIkBkYngtdG9vbHMvdHVubmVsXCI7XG5cbi8qKiBSYXcgY29tbWFuZGVyIGZsYWcgdmFsdWVzIChldmVyeSBudW1lcmljIGZsYWcgYXJyaXZlcyBhcyBhIHN0cmluZykuICovXG5leHBvcnQgaW50ZXJmYWNlIFR1bm5lbE9wdGlvbnMge1xuICB0cmFuc3BvcnQ/OiBpbnRlcmNlcHRvci5UdW5uZWxUcmFuc3BvcnQ7XG4gIHB1YmxpY0RvbWFpbj86IHN0cmluZztcbiAgc3ViZG9tYWluPzogc3RyaW5nO1xuICBwb3J0Pzogc3RyaW5nIHwgbnVtYmVyO1xuICBhcHBQb3J0Pzogc3RyaW5nIHwgbnVtYmVyO1xuICBhbGxvdz86IHN0cmluZ1tdO1xuICBzdWJqZWN0Pzogc3RyaW5nO1xuICBicmFuZE5hbWU/OiBzdHJpbmc7XG4gIG1lc3NhZ2U/OiBzdHJpbmc7XG4gIHNlc3Npb25UdGw/OiBzdHJpbmcgfCBudW1iZXI7XG4gIGNvZGVUdGw/OiBzdHJpbmcgfCBudW1iZXI7XG4gIHNlc3Npb25DdXRvZmY/OiBzdHJpbmc7XG4gIGF1dGhTdG9yYWdlPzogQXV0aFN0b3JhZ2VNb2RlO1xuICBhdXRoU3FsaXRlUGF0aD86IHN0cmluZztcbiAgZm9yd2FyZEhlYWRlcnM/OiBzdHJpbmdbXTtcbiAgZ2F0ZVBhdGg/OiBzdHJpbmdbXTtcbiAgYmluZD86IHN0cmluZ1tdO1xuICBpbnNlY3VyZT86IGJvb2xlYW47XG4gIGZycFNlcnZlcj86IHN0cmluZztcbiAgZnJwUHVibGljRG9tYWluPzogc3RyaW5nO1xuICBmcnBTZXJ2ZXJQb3J0Pzogc3RyaW5nIHwgbnVtYmVyO1xuICBmcnBQcm90b2NvbD86IHN0cmluZztcbiAgZnJwVG9rZW4/OiBzdHJpbmc7XG4gIGZycFByb3h5TmFtZT86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZXNvbHZlZFR1bm5lbE9wdGlvbnMge1xuICAvKiogVGhlIHBvcnQgdGhlIHdyYXBwZXIgaXRzZWxmIGxpc3RlbnMgb24gLSB3aGF0IHBvcnRyIGZvcndhcmRzIHRvLiAqL1xuICBwdWJsaWNQb3J0OiBudW1iZXI7XG4gIC8qKiBUaGUgcHJpdmF0ZSBwb3J0IHRoZSB3cmFwcGVkIGFwcCBpcyB0b2xkIHRvIGJpbmQuIFVuc2V0IG1lYW5zIFwicGljayBvbmVcIi4gKi9cbiAgYXBwUG9ydD86IG51bWJlcjtcbiAgLyoqIEludGVyZmFjZSBJUHMgdGhlIGdhdGUgbGlzdGVucyBvbi4gRW1wdHkgbWVhbnMgdGhlIGRlZmF1bHQgKDAuMC4wLjApLiAqL1xuICBiaW5kSG9zdHM6IHN0cmluZ1tdO1xuICB0cmFuc3BvcnQ6IGludGVyY2VwdG9yLlR1bm5lbFRyYW5zcG9ydDtcbiAgLyoqXG4gICAqIFRoZSBnYXRlIGNvbmZpZyBhcyB0aGUgYGF1dGhHYXRlYCBQTFVHSU4gdGFrZXMgaXQgLSBmbGFncyBvbmx5LCBub3RoaW5nXG4gICAqIHJlc29sdmVkLiBQYXNzZWQgc3RyYWlnaHQgdG8gdGhlIHBsdWdpbiBzbyBpdCBhcHBsaWVzIGl0cyBvd24gZmFsbGJhY2tzXG4gICAqIGV4YWN0bHkgb25jZSwgaW4gdGhlIG9uZSBwbGFjZSB0aGF0IG93bnMgdGhlbS5cbiAgICovXG4gIGdhdGVDb25maWc6IEF1dGhHYXRlQ29uZmlnO1xuICAvKiogVGhlIHNhbWUgY29uZmlnIGFmdGVyIHRoZSBwbHVnaW4ncyByZXNvbHV0aW9uLCBmb3IgYHN0YXR1c2AgYW5kIGZvciByb3V0aW5nLiAqL1xuICBnYXRlOiBwbHVnaW4uUmVzb2x2ZWRBdXRoR2F0ZUNvbmZpZztcbiAgcG9ydHI6IFJldHVyblR5cGU8dHlwZW9mIHBvcnRyLnJlc29sdmVQb3J0ckNvbmZpZz47XG4gIGZycDogUmV0dXJuVHlwZTx0eXBlb2YgZnJwLnJlc29sdmVGcnBDb25maWc+O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZVR1bm5lbE9wdGlvbnMob3B0aW9uczogVHVubmVsT3B0aW9ucyk6IFJlc29sdmVkVHVubmVsT3B0aW9ucyB7XG4gIC8vIFRoZSBEYXRhYnJpY2tzIEFwcHMgcnVudGltZSBjb250cmFjdDogdGhlIHBsYXRmb3JtIHJvdXRlcyB0b1xuICAvLyBEQVRBQlJJQ0tTX0FQUF9QT1JULCBzbyB0aGUgV1JBUFBFUiBjbGFpbXMgaXQgYW5kIHRoZSB3cmFwcGVkIGFwcCBpcyBtb3ZlZFxuICAvLyB0byBhIHByaXZhdGUgb25lLlxuICBjb25zdCBwdWJsaWNQb3J0ID0gY29uZmlnLnBvcnQob3B0aW9ucy5wb3J0LCBcIkRBVEFCUklDS1NfQVBQX1BPUlRcIiwgODAwMCk7XG4gIGNvbnN0IGFwcFBvcnQgPSBjb25maWcucG9ydChvcHRpb25zLmFwcFBvcnQsIFwiQVBQX1BPUlRcIiwgMCwgeyBwcmVmaXg6IFwiVFVOTkVMXCIgfSk7XG4gIGNvbnN0IGdhdGVDb25maWc6IEF1dGhHYXRlQ29uZmlnID0ge1xuICAgIGFsbG93OiBvcHRpb25zLmFsbG93LFxuICAgIHN1YmplY3Q6IG9wdGlvbnMuc3ViamVjdCxcbiAgICBicmFuZE5hbWU6IG9wdGlvbnMuYnJhbmROYW1lLFxuICAgIG1lc3NhZ2U6IG9wdGlvbnMubWVzc2FnZSxcbiAgICAvLyBDb2VyY2VkLCBub3QgcmVzb2x2ZWQ6IHRoZSBwbHVnaW4gb3ducyB0aGUgZW52IG5hbWUgYW5kIHRoZSBkZWZhdWx0IGZvclxuICAgIC8vIHRoZXNlLCBzbyB0aGUgZmxhZyBpcyBwYXNzZWQgdGhyb3VnaCBhcyB0aGUgYGNvbmZpZ2AgdmFsdWUgaXQgZXhwZWN0cyBhbmRcbiAgICAvLyBvbmx5IG5lZWRzIGEgc3RyaW5nIC0+IG51bWJlciBudWRnZSBvbiB0aGUgd2F5LlxuICAgIHNlc3Npb25UdGxTZWNvbmRzOiBvYmplY3QudG9OdW1iZXIob3B0aW9ucy5zZXNzaW9uVHRsKSxcbiAgICBjb2RlVHRsU2Vjb25kczogb2JqZWN0LnRvTnVtYmVyKG9wdGlvbnMuY29kZVR0bCksXG4gICAgc2Vzc2lvbkN1dG9mZjogb3B0aW9ucy5zZXNzaW9uQ3V0b2ZmLFxuICAgIHN0b3JhZ2U6IG9wdGlvbnMuYXV0aFN0b3JhZ2UsXG4gICAgc3FsaXRlUGF0aDogb3B0aW9ucy5hdXRoU3FsaXRlUGF0aCxcbiAgICBmb3J3YXJkSGVhZGVyczogb3B0aW9ucy5mb3J3YXJkSGVhZGVycyxcbiAgICBnYXRlUGF0aHM6IG9wdGlvbnMuZ2F0ZVBhdGgsXG4gICAgaW5zZWN1cmU6IG9wdGlvbnMuaW5zZWN1cmUsXG4gICAgcHVibGljRG9tYWluOiBvcHRpb25zLnB1YmxpY0RvbWFpbixcbiAgICBwdWJsaWNEb21haW5zOiBvcHRpb25zLmZycFB1YmxpY0RvbWFpbiA/IFtvcHRpb25zLmZycFB1YmxpY0RvbWFpbl0gOiB1bmRlZmluZWQsXG4gIH07XG4gIGNvbnN0IGdhdGUgPSBwbHVnaW4ucmVzb2x2ZUF1dGhHYXRlQ29uZmlnKGdhdGVDb25maWcpO1xuICBjb25zdCB0cmFuc3BvcnQgPSBpbnRlcmNlcHRvci5yZXNvbHZlVHVubmVsVHJhbnNwb3J0KG9wdGlvbnMudHJhbnNwb3J0KTtcbiAgcmV0dXJuIHtcbiAgICBwdWJsaWNQb3J0LFxuICAgIC4uLihhcHBQb3J0ID4gMCA/IHsgYXBwUG9ydCB9IDoge30pLFxuICAgIGJpbmRIb3N0czogb3B0aW9ucy5iaW5kID8/IFtdLFxuICAgIHRyYW5zcG9ydCxcbiAgICBnYXRlQ29uZmlnLFxuICAgIGdhdGUsXG4gICAgcG9ydHI6IHBvcnRyLnJlc29sdmVQb3J0ckNvbmZpZyh7XG4gICAgICBwdWJsaWNEb21haW46IGdhdGUucHVibGljRG9tYWluLFxuICAgICAgc3ViZG9tYWluOiBvcHRpb25zLnN1YmRvbWFpbixcbiAgICAgIHBvcnQ6IHB1YmxpY1BvcnQsXG4gICAgfSksXG4gICAgZnJwOiBmcnAucmVzb2x2ZUZycENvbmZpZyh7XG4gICAgICBwdWJsaWNEb21haW46IG9wdGlvbnMuZnJwUHVibGljRG9tYWluLFxuICAgICAgc2VydmVyOiBvcHRpb25zLmZycFNlcnZlcixcbiAgICAgIHNlcnZlclBvcnQ6IG9wdGlvbnMuZnJwU2VydmVyUG9ydCxcbiAgICAgIHByb3RvY29sOiBvcHRpb25zLmZycFByb3RvY29sLFxuICAgICAgdG9rZW46IG9wdGlvbnMuZnJwVG9rZW4sXG4gICAgICBwcm94eU5hbWU6IG9wdGlvbnMuZnJwUHJveHlOYW1lLFxuICAgICAgcG9ydDogcHVibGljUG9ydCxcbiAgICB9KSxcbiAgfTtcbn1cbiJdfQ==
|
package/package.json
CHANGED
|
@@ -24,13 +24,13 @@
|
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@databricks/appkit": "^0.43.0",
|
|
27
|
-
"@dbx-tools/appkit": "0.6.
|
|
28
|
-
"@dbx-tools/auth": "0.6.
|
|
29
|
-
"@dbx-tools/core": "0.6.
|
|
30
|
-
"@dbx-tools/email": "0.6.
|
|
31
|
-
"@dbx-tools/shared-core": "0.6.
|
|
32
|
-
"@dbx-tools/shared-email": "0.6.
|
|
33
|
-
"@dbx-tools/tunnel": "0.6.
|
|
27
|
+
"@dbx-tools/appkit": "0.6.107",
|
|
28
|
+
"@dbx-tools/auth": "0.6.107",
|
|
29
|
+
"@dbx-tools/core": "0.6.107",
|
|
30
|
+
"@dbx-tools/email": "0.6.107",
|
|
31
|
+
"@dbx-tools/shared-core": "0.6.107",
|
|
32
|
+
"@dbx-tools/shared-email": "0.6.107",
|
|
33
|
+
"@dbx-tools/tunnel": "0.6.107",
|
|
34
34
|
"commander": "^15.0.0",
|
|
35
35
|
"http-proxy-3": "^1.23.1"
|
|
36
36
|
},
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"./package.json": "./package.json"
|
|
65
65
|
}
|
|
66
66
|
},
|
|
67
|
-
"version": "0.6.
|
|
67
|
+
"version": "0.6.107",
|
|
68
68
|
"types": "./lib/index.d.ts",
|
|
69
69
|
"type": "module",
|
|
70
70
|
"exports": {
|
package/src/cli.ts
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
import { type ChildProcess, spawn } from "node:child_process";
|
|
26
26
|
import { createServer } from "node:net";
|
|
27
27
|
import { log } from "@dbx-tools/shared-core";
|
|
28
|
-
import { portr } from "@dbx-tools/tunnel";
|
|
28
|
+
import { frp, portr } from "@dbx-tools/tunnel";
|
|
29
29
|
import { Command, CommanderError } from "commander";
|
|
30
30
|
import { resolveTunnelOptions, type TunnelOptions } from "./options.ts";
|
|
31
31
|
import { startProxy } from "./proxy.ts";
|
|
@@ -61,7 +61,8 @@ function freePort(): Promise<number> {
|
|
|
61
61
|
*/
|
|
62
62
|
function addOptions(command: Command): Command {
|
|
63
63
|
return command
|
|
64
|
-
.option("--
|
|
64
|
+
.option("--transport <transport>", "public tunnel transport: portr, frp, or both")
|
|
65
|
+
.option("--public-domain <host>", "public tunnel domain")
|
|
65
66
|
.option("--subdomain <name>", "portr subdomain (else derived from the public domain)")
|
|
66
67
|
.option("--port <port>", "public port the wrapper listens on")
|
|
67
68
|
.option("--app-port <port>", "private port the wrapped app is told to bind")
|
|
@@ -77,6 +78,12 @@ function addOptions(command: Command): Command {
|
|
|
77
78
|
.option("--forward-headers <patterns...>", "extra x- headers tunnel traffic may forward")
|
|
78
79
|
.option("--gate-path <prefix...>", "path prefixes to gate beyond /api/ (e.g. /ws)")
|
|
79
80
|
.option("--bind <host...>", "interface IPs the gate listens on (default: 0.0.0.0)")
|
|
81
|
+
.option("--frp-server <host>", "frps control host (default: FRP public domain)")
|
|
82
|
+
.option("--frp-public-domain <host>", "FRP public HTTP domain")
|
|
83
|
+
.option("--frp-server-port <port>", "frps control port (default: 443)")
|
|
84
|
+
.option("--frp-protocol <protocol>", "frpc transport protocol (default: wss)")
|
|
85
|
+
.option("--frp-token <token>", "frps auth token")
|
|
86
|
+
.option("--frp-proxy-name <name>", "frp proxy registration name")
|
|
80
87
|
.option("--insecure", "run open, with no gate");
|
|
81
88
|
}
|
|
82
89
|
|
|
@@ -158,15 +165,21 @@ async function run(raw: TunnelOptions, command: readonly string[]): Promise<void
|
|
|
158
165
|
bindHosts: resolved.bindHosts,
|
|
159
166
|
});
|
|
160
167
|
|
|
161
|
-
if (resolved.portr) {
|
|
168
|
+
if ((resolved.transport === "portr" || resolved.transport === "both") && resolved.portr) {
|
|
162
169
|
const portrEnv = await portr.installPortr();
|
|
163
170
|
await portr.writePortrConfig(resolved.portr, portrEnv);
|
|
164
171
|
children.push(await portr.startPortr(resolved.portr, portrEnv));
|
|
165
|
-
} else {
|
|
166
|
-
logger.info("no PORTR_TOKEN / TUNNEL_PUBLIC_DOMAIN - serving locally only", {
|
|
167
|
-
publicPort: resolved.publicPort,
|
|
168
|
-
});
|
|
169
172
|
}
|
|
173
|
+
if ((resolved.transport === "frp" || resolved.transport === "both") && resolved.frp) {
|
|
174
|
+
const frpEnv = await frp.installFrp();
|
|
175
|
+
const configPath = await frp.writeFrpConfig(resolved.frp, frpEnv);
|
|
176
|
+
children.push(frp.startFrp(resolved.frp, frpEnv, configPath));
|
|
177
|
+
}
|
|
178
|
+
const activeTunnelCount = children.length - (executable ? 1 : 0);
|
|
179
|
+
if (!activeTunnelCount) logger.info("no selected public tunnel is configured", {
|
|
180
|
+
transport: resolved.transport,
|
|
181
|
+
publicPort: resolved.publicPort,
|
|
182
|
+
});
|
|
170
183
|
supervise(children);
|
|
171
184
|
}
|
|
172
185
|
|
|
@@ -175,7 +188,7 @@ export function buildProgram(name = "dbx tunnel"): Command {
|
|
|
175
188
|
const program = addOptions(
|
|
176
189
|
new Command()
|
|
177
190
|
.name(name)
|
|
178
|
-
.description("Front a command with a
|
|
191
|
+
.description("Front a command with a public tunnel and passwordless auth"),
|
|
179
192
|
);
|
|
180
193
|
|
|
181
194
|
// `run` is the DEFAULT action as well as a named subcommand, preserving the old
|
|
@@ -205,9 +218,14 @@ export function buildProgram(name = "dbx tunnel"): Command {
|
|
|
205
218
|
|
|
206
219
|
program
|
|
207
220
|
.command("install")
|
|
208
|
-
.
|
|
209
|
-
.
|
|
210
|
-
|
|
221
|
+
.argument("[transport]", "portr, frp, or both", "portr")
|
|
222
|
+
.description("Install public tunnel client binaries and exit")
|
|
223
|
+
.action(async (transport: string) => {
|
|
224
|
+
if (transport === "portr" || transport === "both") await portr.installPortr();
|
|
225
|
+
if (transport === "frp" || transport === "both") await frp.installFrp();
|
|
226
|
+
if (transport !== "portr" && transport !== "frp" && transport !== "both") {
|
|
227
|
+
throw new CommanderError(1, "tunnel.invalid-transport", `invalid transport: ${transport}`);
|
|
228
|
+
}
|
|
211
229
|
});
|
|
212
230
|
|
|
213
231
|
return program;
|
package/src/options.ts
CHANGED
|
@@ -15,10 +15,11 @@
|
|
|
15
15
|
import type { AuthStorageMode } from "@dbx-tools/auth";
|
|
16
16
|
import { config } from "@dbx-tools/core";
|
|
17
17
|
import { object } from "@dbx-tools/shared-core";
|
|
18
|
-
import { type AuthGateConfig, plugin, portr } from "@dbx-tools/tunnel";
|
|
18
|
+
import { type AuthGateConfig, frp, interceptor, plugin, portr } from "@dbx-tools/tunnel";
|
|
19
19
|
|
|
20
20
|
/** Raw commander flag values (every numeric flag arrives as a string). */
|
|
21
21
|
export interface TunnelOptions {
|
|
22
|
+
transport?: interceptor.TunnelTransport;
|
|
22
23
|
publicDomain?: string;
|
|
23
24
|
subdomain?: string;
|
|
24
25
|
port?: string | number;
|
|
@@ -36,6 +37,12 @@ export interface TunnelOptions {
|
|
|
36
37
|
gatePath?: string[];
|
|
37
38
|
bind?: string[];
|
|
38
39
|
insecure?: boolean;
|
|
40
|
+
frpServer?: string;
|
|
41
|
+
frpPublicDomain?: string;
|
|
42
|
+
frpServerPort?: string | number;
|
|
43
|
+
frpProtocol?: string;
|
|
44
|
+
frpToken?: string;
|
|
45
|
+
frpProxyName?: string;
|
|
39
46
|
}
|
|
40
47
|
|
|
41
48
|
export interface ResolvedTunnelOptions {
|
|
@@ -45,6 +52,7 @@ export interface ResolvedTunnelOptions {
|
|
|
45
52
|
appPort?: number;
|
|
46
53
|
/** Interface IPs the gate listens on. Empty means the default (0.0.0.0). */
|
|
47
54
|
bindHosts: string[];
|
|
55
|
+
transport: interceptor.TunnelTransport;
|
|
48
56
|
/**
|
|
49
57
|
* The gate config as the `authGate` PLUGIN takes it - flags only, nothing
|
|
50
58
|
* resolved. Passed straight to the plugin so it applies its own fallbacks
|
|
@@ -54,6 +62,7 @@ export interface ResolvedTunnelOptions {
|
|
|
54
62
|
/** The same config after the plugin's resolution, for `status` and for routing. */
|
|
55
63
|
gate: plugin.ResolvedAuthGateConfig;
|
|
56
64
|
portr: ReturnType<typeof portr.resolvePortrConfig>;
|
|
65
|
+
frp: ReturnType<typeof frp.resolveFrpConfig>;
|
|
57
66
|
}
|
|
58
67
|
|
|
59
68
|
export function resolveTunnelOptions(options: TunnelOptions): ResolvedTunnelOptions {
|
|
@@ -79,12 +88,15 @@ export function resolveTunnelOptions(options: TunnelOptions): ResolvedTunnelOpti
|
|
|
79
88
|
gatePaths: options.gatePath,
|
|
80
89
|
insecure: options.insecure,
|
|
81
90
|
publicDomain: options.publicDomain,
|
|
91
|
+
publicDomains: options.frpPublicDomain ? [options.frpPublicDomain] : undefined,
|
|
82
92
|
};
|
|
83
93
|
const gate = plugin.resolveAuthGateConfig(gateConfig);
|
|
94
|
+
const transport = interceptor.resolveTunnelTransport(options.transport);
|
|
84
95
|
return {
|
|
85
96
|
publicPort,
|
|
86
97
|
...(appPort > 0 ? { appPort } : {}),
|
|
87
98
|
bindHosts: options.bind ?? [],
|
|
99
|
+
transport,
|
|
88
100
|
gateConfig,
|
|
89
101
|
gate,
|
|
90
102
|
portr: portr.resolvePortrConfig({
|
|
@@ -92,5 +104,14 @@ export function resolveTunnelOptions(options: TunnelOptions): ResolvedTunnelOpti
|
|
|
92
104
|
subdomain: options.subdomain,
|
|
93
105
|
port: publicPort,
|
|
94
106
|
}),
|
|
107
|
+
frp: frp.resolveFrpConfig({
|
|
108
|
+
publicDomain: options.frpPublicDomain,
|
|
109
|
+
server: options.frpServer,
|
|
110
|
+
serverPort: options.frpServerPort,
|
|
111
|
+
protocol: options.frpProtocol,
|
|
112
|
+
token: options.frpToken,
|
|
113
|
+
proxyName: options.frpProxyName,
|
|
114
|
+
port: publicPort,
|
|
115
|
+
}),
|
|
95
116
|
};
|
|
96
117
|
}
|