@dbx-tools/lakebox 0.0.0-stage → 0.9.132

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.
@@ -0,0 +1,309 @@
1
+ import { createHash } from "node:crypto";
2
+ import { isIP } from "node:net";
3
+ import { errorUtils, log } from "@dbx-tools/shared-core";
4
+ import ssh2 from "ssh2";
5
+ import { z } from "zod";
6
+ import { createSshTransport, SshCommand, sshCommandScript, } from "./_ssh.js";
7
+ export { SshCommand, sshCommandScript } from "./_ssh.js";
8
+ const { Client } = ssh2;
9
+ const logger = log.logger("lakebox:ssh");
10
+ const SERVICE_DIRECT_SUFFIX = ".service-direct.cloud.databricks.com";
11
+ const DnsAnswerSchema = z
12
+ .object({
13
+ type: z.number().int().describe("DNS record type number."),
14
+ data: z.string().describe("DNS record value."),
15
+ })
16
+ .passthrough()
17
+ .describe("One DNS-over-HTTPS answer record.");
18
+ const DnsResponseSchema = z
19
+ .object({
20
+ Answer: z.array(DnsAnswerSchema).optional().describe("Resolved DNS answer records."),
21
+ })
22
+ .passthrough()
23
+ .describe("Google DNS-over-HTTPS JSON response.");
24
+ /**
25
+ * Verified SSH session that delegates commands and remote TCP connections to
26
+ * the transport selected by `src/_ssh.ts`.
27
+ *
28
+ * The initial ssh2 handshake verifies and persists the Databricks gateway host
29
+ * key. The selected transport then starts its pooled command and forwarding
30
+ * resources. Resolved transport and patch policy determine whether the verified
31
+ * client seeds the ssh2 pool or is replaced by native OpenSSH ControlMasters.
32
+ */
33
+ export class SshSession {
34
+ options;
35
+ activeCommands = new Set();
36
+ pendingClients = new Set();
37
+ transport;
38
+ connecting;
39
+ closing;
40
+ knownHost;
41
+ closed = false;
42
+ /** Creates a disconnected session. Call {@link connect} or another operation to connect. */
43
+ constructor(options) {
44
+ this.options = options;
45
+ this.knownHost = options.knownHost;
46
+ }
47
+ /**
48
+ * Verifies the gateway, resolves its public fallback when necessary, and
49
+ * selects the command and forwarding transport.
50
+ */
51
+ async connect() {
52
+ if (this.closed)
53
+ throw new Error("SSH session is closed");
54
+ if (this.transport)
55
+ return;
56
+ if (this.connecting)
57
+ return this.connecting;
58
+ this.connecting = this.connectWithFallback().catch((error) => {
59
+ this.connecting = undefined;
60
+ throw error;
61
+ });
62
+ return this.connecting;
63
+ }
64
+ async connectWithFallback() {
65
+ try {
66
+ await this.connectHost(this.options.host);
67
+ }
68
+ catch (error) {
69
+ if (!shouldResolvePublicGateway(this.options.host, error))
70
+ throw error;
71
+ const resolveAddresses = this.options.resolvePublicAddresses ?? resolvePublicGatewayAddresses;
72
+ let addresses;
73
+ try {
74
+ addresses = await resolveAddresses(this.options.host);
75
+ }
76
+ catch (resolveError) {
77
+ logger.warn("public Lakebox gateway resolution failed", {
78
+ host: this.options.host,
79
+ error: errorUtils.toError(resolveError),
80
+ });
81
+ throw error;
82
+ }
83
+ logger.warn("private Lakebox gateway unreachable; retrying public addresses", {
84
+ host: this.options.host,
85
+ addressCount: addresses.length,
86
+ });
87
+ let lastError = error;
88
+ for (const address of addresses) {
89
+ try {
90
+ await this.connectHost(address);
91
+ return;
92
+ }
93
+ catch (connectError) {
94
+ lastError = connectError;
95
+ }
96
+ }
97
+ throw lastError;
98
+ }
99
+ }
100
+ async connectHost(connectHost) {
101
+ if (this.closed)
102
+ throw new Error("SSH session is closed");
103
+ const client = await this.createVerifiedClient(connectHost, true);
104
+ if (this.closed) {
105
+ client.destroy();
106
+ throw new Error("SSH session is closed");
107
+ }
108
+ try {
109
+ const transport = await createSshTransport({
110
+ host: this.options.host,
111
+ connectHost,
112
+ port: this.options.port,
113
+ username: this.options.username,
114
+ privateKeyPath: this.options.privateKeyPath,
115
+ knownHostsPath: this.options.knownHostsPath,
116
+ connectTimeoutMs: this.options.connectTimeoutMs,
117
+ ssh2Client: client,
118
+ createSsh2CommandClient: () => this.createVerifiedClient(connectHost, false),
119
+ transport: this.options.sshTransport,
120
+ ssh2Patch: this.options.ssh2Patch,
121
+ ...(this.options.sshCommand ? { sshCommand: this.options.sshCommand } : {}),
122
+ });
123
+ if (this.closed) {
124
+ await transport.close();
125
+ throw new Error("SSH session is closed");
126
+ }
127
+ this.transport = transport;
128
+ this.connecting = undefined;
129
+ if (transport.kind === "openssh")
130
+ client.destroy();
131
+ }
132
+ catch (error) {
133
+ client.destroy();
134
+ throw error;
135
+ }
136
+ }
137
+ createVerifiedClient(connectHost, rememberHost) {
138
+ return new Promise((resolve, reject) => {
139
+ if (this.closed) {
140
+ reject(new Error("SSH session is closed"));
141
+ return;
142
+ }
143
+ const client = new Client();
144
+ this.pendingClients.add(client);
145
+ let verifiedHost;
146
+ let settled = false;
147
+ const finishSettlement = () => {
148
+ this.pendingClients.delete(client);
149
+ };
150
+ client.once("ready", () => {
151
+ const finish = async () => {
152
+ if (!verifiedHost)
153
+ throw new Error("SSH gateway did not provide a verified host key");
154
+ this.knownHost = verifiedHost.fingerprint;
155
+ if (rememberHost) {
156
+ await this.options.rememberHost?.(verifiedHost.fingerprint, verifiedHost.key);
157
+ }
158
+ settled = true;
159
+ finishSettlement();
160
+ resolve(client);
161
+ };
162
+ void finish().catch((error) => {
163
+ client.destroy();
164
+ if (settled)
165
+ return;
166
+ settled = true;
167
+ finishSettlement();
168
+ reject(error);
169
+ });
170
+ });
171
+ client.once("error", (error) => {
172
+ if (settled)
173
+ return;
174
+ settled = true;
175
+ finishSettlement();
176
+ reject(error);
177
+ });
178
+ client.once("close", () => {
179
+ if (settled)
180
+ return;
181
+ settled = true;
182
+ finishSettlement();
183
+ reject(new Error("SSH gateway closed before authentication completed"));
184
+ });
185
+ try {
186
+ client.connect({
187
+ host: connectHost,
188
+ port: this.options.port,
189
+ username: this.options.username,
190
+ privateKey: this.options.privateKey,
191
+ readyTimeout: this.options.connectTimeoutMs,
192
+ keepaliveInterval: 15_000,
193
+ keepaliveCountMax: 3,
194
+ hostVerifier: (key) => {
195
+ const fingerprint = createHash("sha256").update(key).digest("base64");
196
+ if (this.knownHost && fingerprint !== this.knownHost)
197
+ return false;
198
+ verifiedHost = { fingerprint, key: Buffer.from(key) };
199
+ return true;
200
+ },
201
+ });
202
+ }
203
+ catch (error) {
204
+ settled = true;
205
+ finishSettlement();
206
+ client.destroy();
207
+ reject(error);
208
+ }
209
+ });
210
+ }
211
+ /**
212
+ * Starts one command as a Lakebox user and returns its live output and
213
+ * completion state immediately.
214
+ */
215
+ execute(command, args, options) {
216
+ const { user, ...rest } = options;
217
+ return this.startCommand(command, args, rest, { kind: "user", ...user });
218
+ }
219
+ /**
220
+ * @internal Starts one fixed package-owned bootstrap command as root.
221
+ *
222
+ * Never route REST, agent-tool, service, or environment input here.
223
+ */
224
+ executePrivileged(command, args, options) {
225
+ return this.startCommand(command, args, options, { kind: "root" });
226
+ }
227
+ startCommand(command, args, options, identity) {
228
+ const script = sshCommandScript(command, args, options.cwd, options.env, identity);
229
+ const sshCommand = new SshCommand(command, args, options, async (execution) => {
230
+ await this.connect();
231
+ if (execution.signal.aborted)
232
+ return 130;
233
+ const transport = this.transport;
234
+ if (!transport)
235
+ throw new Error("SSH transport did not initialize");
236
+ return transport.run(script, execution);
237
+ });
238
+ this.activeCommands.add(sshCommand);
239
+ const remove = () => this.activeCommands.delete(sshCommand);
240
+ void sshCommand.result.then(remove, remove);
241
+ return sshCommand;
242
+ }
243
+ /** Opens a remote TCP connection through native SOCKS5 or ssh2 direct forwarding. */
244
+ async forwardOut(remoteHost, remotePort) {
245
+ await this.connect();
246
+ const transport = this.transport;
247
+ if (!transport)
248
+ throw new Error("SSH transport did not initialize");
249
+ return transport.connect(remoteHost, remotePort);
250
+ }
251
+ /** Cancels active commands, closes the selected transport, and clears connection state. */
252
+ close() {
253
+ if (this.closing)
254
+ return this.closing;
255
+ this.closed = true;
256
+ this.closing = this.closeResources();
257
+ return this.closing;
258
+ }
259
+ async closeResources() {
260
+ const cancellations = [...this.activeCommands].map((command) => command.cancel());
261
+ this.activeCommands.clear();
262
+ for (const client of this.pendingClients)
263
+ client.destroy();
264
+ this.pendingClients.clear();
265
+ const transport = this.transport;
266
+ const connecting = this.connecting;
267
+ this.transport = undefined;
268
+ this.connecting = undefined;
269
+ const results = await Promise.allSettled([
270
+ ...cancellations,
271
+ ...(transport ? [transport.close()] : []),
272
+ ...(connecting ? [connecting] : []),
273
+ ]);
274
+ for (const result of results) {
275
+ if (result.status === "rejected") {
276
+ logger.warn("failed to close SSH session resource", {
277
+ error: errorUtils.toError(result.reason),
278
+ });
279
+ }
280
+ }
281
+ }
282
+ }
283
+ /**
284
+ * Resolves public IPv4 addresses for a Databricks service-direct gateway.
285
+ *
286
+ * Returns an empty list for other hostnames. DNS-over-HTTPS requests time out
287
+ * after five seconds and reject invalid responses.
288
+ */
289
+ export async function resolvePublicGatewayAddresses(host, fetcher = fetch) {
290
+ if (!host.toLowerCase().endsWith(SERVICE_DIRECT_SUFFIX))
291
+ return [];
292
+ const response = await fetcher(`https://dns.google/resolve?name=${encodeURIComponent(host)}&type=A`, { headers: { Accept: "application/dns-json" }, signal: AbortSignal.timeout(5_000) });
293
+ if (!response.ok)
294
+ throw new Error(`Public DNS resolution failed (${response.status})`);
295
+ const payload = DnsResponseSchema.parse(await response.json());
296
+ return [
297
+ ...new Set((payload.Answer ?? [])
298
+ .filter((answer) => answer.type === 1 && isIP(answer.data) === 4)
299
+ .map((answer) => answer.data)),
300
+ ];
301
+ }
302
+ function shouldResolvePublicGateway(host, error) {
303
+ if (!host.toLowerCase().endsWith(SERVICE_DIRECT_SUFFIX))
304
+ return false;
305
+ const code = error?.code ??
306
+ error?.cause?.code;
307
+ return code === "EHOSTUNREACH" || code === "ENETUNREACH" || code === "ETIMEDOUT";
308
+ }
309
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Vzc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXNzaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDekMsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUVoQyxPQUFPLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3pELE9BQU8sSUFBbUMsTUFBTSxNQUFNLENBQUM7QUFDdkQsT0FBTyxFQUFFLENBQUMsRUFBRSxNQUFNLEtBQUssQ0FBQztBQUN4QixPQUFPLEVBQ0wsa0JBQWtCLEVBQ2xCLFVBQVUsRUFDVixnQkFBZ0IsR0FHakIsTUFBTSxXQUFXLENBQUM7QUFHbkIsT0FBTyxFQUFFLFVBQVUsRUFBRSxnQkFBZ0IsRUFBMkIsTUFBTSxXQUFXLENBQUM7QUFFbEYsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQztBQUN4QixNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0FBQ3pDLE1BQU0scUJBQXFCLEdBQUcsc0NBQXNDLENBQUM7QUFFckUsTUFBTSxlQUFlLEdBQUcsQ0FBQztLQUN0QixNQUFNLENBQUM7SUFDTixJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLFFBQVEsQ0FBQyx5QkFBeUIsQ0FBQztJQUMxRCxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQztDQUMvQyxDQUFDO0tBQ0QsV0FBVyxFQUFFO0tBQ2IsUUFBUSxDQUFDLG1DQUFtQyxDQUFDLENBQUM7QUFFakQsTUFBTSxpQkFBaUIsR0FBRyxDQUFDO0tBQ3hCLE1BQU0sQ0FBQztJQUNOLE1BQU0sRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLGVBQWUsQ0FBQyxDQUFD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LElBQUksSUFBSSxLQUFLLFdBQVcsQ0FBQztBQUNuRixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgY3JlYXRlSGFzaCB9IGZyb20gXCJub2RlOmNyeXB0b1wiO1xuaW1wb3J0IHsgaXNJUCB9IGZyb20gXCJub2RlOm5ldFwiO1xuaW1wb3J0IHR5cGUgeyBEdXBsZXggfSBmcm9tIFwibm9kZTpzdHJlYW1cIjtcbmltcG9ydCB7IGVycm9yVXRpbHMsIGxvZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgc3NoMiwgeyB0eXBlIENsaWVudCBhcyBTc2gyQ2xpZW50IH0gZnJvbSBcInNzaDJcIjtcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5pbXBvcnQge1xuICBjcmVhdGVTc2hUcmFuc3BvcnQsXG4gIFNzaENvbW1hbmQsXG4gIHNzaENvbW1hbmRTY3JpcHQsXG4gIHR5cGUgU3NoQ29tbWFuZElkZW50aXR5LFxuICB0eXBlIFNzaFRyYW5zcG9ydCxcbn0gZnJvbSBcIi4vX3NzaC50c1wiO1xuaW1wb3J0IHR5cGUgeyBTc2gyUGF0Y2hNb2RlLCBTc2hUcmFuc3BvcnRNb2RlIH0gZnJvbSBcIi4vdHJhbnNwb3J0LnRzXCI7XG5cbmV4cG9ydCB7IFNzaENvbW1hbmQsIHNzaENvbW1hbmRTY3JpcHQsIHR5cGUgU3NoQ29tbWFuZElkZW50aXR5IH0gZnJvbSBcIi4vX3NzaC50c1wiO1xuXG5jb25zdCB7IENsaWVudCB9ID0gc3NoMjtcbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJsYWtlYm94OnNzaFwiKTtcbmNvbnN0IFNFUlZJQ0VfRElSRUNUX1NVRkZJWCA9IFwiLnNlcnZpY2UtZGlyZWN0LmNsb3VkLmRhdGFicmlja3MuY29tXCI7XG5cbmNvbnN0IERuc0Fuc3dlclNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgdHlwZTogei5udW1iZXIoKS5pbnQoKS5kZXNjcmliZShcIkROUyByZWNvcmQgdHlwZSBudW1iZXIuXCIpLFxuICAgIGRhdGE6IHouc3RyaW5nKCkuZGVzY3JpYmUoXCJETlMgcmVjb3JkIHZhbHVlLlwiKSxcbiAgfSlcbiAgLnBhc3N0aHJvdWdoKClcbiAgLmRlc2NyaWJlKFwiT25lIEROUy1vdmVyLUhUVFBTIGFuc3dlciByZWNvcmQuXCIpO1xuXG5jb25zdCBEbnNSZXNwb25zZVNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgQW5zd2VyOiB6LmFycmF5KERuc0Fuc3dlclNjaGVtYSkub3B0aW9uYWwoKS5kZXNjcmliZShcIlJlc29sdmVkIEROUyBhbnN3ZXIgcmVjb3Jkcy5cIiksXG4gIH0pXG4gIC5wYXNzdGhyb3VnaCgpXG4gIC5kZXNjcmliZShcIkdvb2dsZSBETlMtb3Zlci1IVFRQUyBKU09OIHJlc3BvbnNlLlwiKTtcblxuLyoqIENvbm5lY3Rpb24sIGtleSwgaG9zdC12ZXJpZmljYXRpb24sIGFuZCBjb21tYW5kIHNldHRpbmdzIGZvciBvbmUgU1NIIG1hY2hpbmUuICovXG5leHBvcnQgaW50ZXJmYWNlIFNzaFNlc3Npb25PcHRpb25zIHtcbiAgLyoqIERhdGFicmlja3MgTGFrZWJveCBnYXRld2F5IGhvc3RuYW1lLiAqL1xuICBob3N0OiBzdHJpbmc7XG4gIC8qKiBTU0ggZ2F0ZXdheSBwb3J0LiAqL1xuICBwb3J0OiBudW1iZXI7XG4gIC8qKiBTU0ggdXNlcm5hbWUgYWNjZXB0ZWQgYnkgdGhlIGdhdGV3YXk6IHRoZSBMYWtlYm94IElELiAqL1xuICB1c2VybmFtZTogc3RyaW5nO1xuICAvKiogSW4tbWVtb3J5IHByaXZhdGUga2V5IHVzZWQgZm9yIHRoZSB2ZXJpZmllZCBTU0ggaGFuZHNoYWtlIGFuZCBzc2gyIGZhbGxiYWNrLiAqL1xuICBwcml2YXRlS2V5OiBzdHJpbmc7XG4gIC8qKiBQcml2YXRlIGtleSBmaWxlIHVzZWQgYnkgbmF0aXZlIE9wZW5TU0guICovXG4gIHByaXZhdGVLZXlQYXRoOiBzdHJpbmc7XG4gIC8qKiBEZWRpY2F0ZWQgT3BlblNTSCBrbm93bi1ob3N0IGZpbGUgZm9yIHRoaXMgd29ya3NwYWNlLCB1c2VyLCBhbmQgZ2F0ZXdheS4gKi9cbiAga25vd25Ib3N0c1BhdGg6IHN0cmluZztcbiAgLyoqIENvbm5lY3Rpb24gdGltZW91dCBpbiBtaWxsaXNlY29uZHMuICovXG4gIGNvbm5lY3RUaW1lb3V0TXM6IG51bWJlcjtcbiAgLyoqIFNTSCB0cmFuc3BvcnQgc2VsZWN0ZWQgZm9yIHRoaXMgc2Vzc2lvbi4gKi9cbiAgc3NoVHJhbnNwb3J0OiBTc2hUcmFuc3BvcnRNb2RlO1xuICAvKiogc3NoMiBtaXNzaW5nLWV4ZWMtcmVwbHkgcGF0Y2ggcG9saWN5LiAqL1xuICBzc2gyUGF0Y2g6IFNzaDJQYXRjaE1vZGU7XG4gIC8qKiBQcmV2aW91c2x5IHRydXN0ZWQgU0hBLTI1NiBob3N0LWtleSBmaW5nZXJwcmludC4gKi9cbiAga25vd25Ib3N0Pzogc3RyaW5nO1xuICAvKiogUGVyc2lzdHMgdGhlIGFjY2VwdGVkIGhvc3Qga2V5IGZvciBib3RoIHNzaDIgYW5kIG5hdGl2ZSBPcGVuU1NILiAqL1xuICByZW1lbWJlckhvc3Q/OiAoZmluZ2VycHJpbnQ6IHN0cmluZywga2V5OiBCdWZmZXIpID0+IFByb21pc2U8dm9pZD47XG4gIC8qKiBOYXRpdmUgT3BlblNTSCBleGVjdXRhYmxlLiBEZWZhdWx0cyB0byBgc3NoYCBvbiBgUEFUSGAuICovXG4gIHNzaENvbW1hbmQ/OiBzdHJpbmc7XG4gIC8qKiBSZXNvbHZlcyBwdWJsaWMgZmFsbGJhY2sgYWRkcmVzc2VzIGZvciBhIHNlcnZpY2UtZGlyZWN0IGdhdGV3YXkuICovXG4gIHJlc29sdmVQdWJsaWNBZGRyZXNzZXM/OiAoaG9zdDogc3RyaW5nKSA9PiBQcm9taXNlPHN0cmluZ1tdPjtcbn1cblxuLyoqXG4gKiBWZXJpZmllZCBTU0ggc2Vzc2lvbiB0aGF0IGRlbGVnYXRlcyBjb21tYW5kcyBhbmQgcmVtb3RlIFRDUCBjb25uZWN0aW9ucyB0b1xuICogdGhlIHRyYW5zcG9ydCBzZWxlY3RlZCBieSBgc3JjL19zc2gudHNgLlxuICpcbiAqIFRoZSBpbml0aWFsIHNzaDIgaGFuZHNoYWtlIHZlcmlmaWVzIGFuZCBwZXJzaXN0cyB0aGUgRGF0YWJyaWNrcyBnYXRld2F5IGhvc3RcbiAqIGtleS4gVGhlIHNlbGVjdGVkIHRyYW5zcG9ydCB0aGVuIHN0YXJ0cyBpdHMgcG9vbGVkIGNvbW1hbmQgYW5kIGZvcndhcmRpbmdcbiAqIHJlc291cmNlcy4gUmVzb2x2ZWQgdHJhbnNwb3J0IGFuZCBwYXRjaCBwb2xpY3kgZGV0ZXJtaW5lIHdoZXRoZXIgdGhlIHZlcmlmaWVkXG4gKiBjbGllbnQgc2VlZHMgdGhlIHNzaDIgcG9vbCBvciBpcyByZXBsYWNlZCBieSBuYXRpdmUgT3BlblNTSCBDb250cm9sTWFzdGVycy5cbiAqL1xuZXhwb3J0IGNsYXNzIFNzaFNlc3Npb24ge1xuICBwcml2YXRlIHJlYWRvbmx5IGFjdGl2ZUNvbW1hbmRzID0gbmV3IFNldDxTc2hDb21tYW5kPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IHBlbmRpbmdDbGllbnRzID0gbmV3IFNldDxTc2gyQ2xpZW50PigpO1xuICBwcml2YXRlIHRyYW5zcG9ydD86IFNzaFRyYW5zcG9ydDtcbiAgcHJpdmF0ZSBjb25uZWN0aW5nPzogUHJvbWlzZTx2b2lkPjtcbiAgcHJpdmF0ZSBjbG9zaW5nPzogUHJvbWlzZTx2b2lkPjtcbiAgcHJpdmF0ZSBrbm93bkhvc3Q/OiBzdHJpbmc7XG4gIHByaXZhdGUgY2xvc2VkID0gZmFsc2U7XG5cbiAgLyoqIENyZWF0ZXMgYSBkaXNjb25uZWN0ZWQgc2Vzc2lvbi4gQ2FsbCB7QGxpbmsgY29ubmVjdH0gb3IgYW5vdGhlciBvcGVyYXRpb24gdG8gY29ubmVjdC4gKi9cbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBvcHRpb25zOiBTc2hTZXNzaW9uT3B0aW9ucykge1xuICAgIHRoaXMua25vd25Ib3N0ID0gb3B0aW9ucy5rbm93bkhvc3Q7XG4gIH1cblxuICAvKipcbiAgICogVmVyaWZpZXMgdGhlIGdhdGV3YXksIHJlc29sdmVzIGl0cyBwdWJsaWMgZmFsbGJhY2sgd2hlbiBuZWNlc3NhcnksIGFuZFxuICAgKiBzZWxlY3RzIHRoZSBjb21tYW5kIGFuZCBmb3J3YXJkaW5nIHRyYW5zcG9ydC5cbiAgICovXG4gIGFzeW5jIGNvbm5lY3QoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuY2xvc2VkKSB0aHJvdyBuZXcgRXJyb3IoXCJTU0ggc2Vzc2lvbiBpcyBjbG9zZWRcIik7XG4gICAgaWYgKHRoaXMudHJhbnNwb3J0KSByZXR1cm47XG4gICAgaWYgKHRoaXMuY29ubmVjdGluZykgcmV0dXJuIHRoaXMuY29ubmVjdGluZztcbiAgICB0aGlzLmNvbm5lY3RpbmcgPSB0aGlzLmNvbm5lY3RXaXRoRmFsbGJhY2soKS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgIHRoaXMuY29ubmVjdGluZyA9IHVuZGVmaW5lZDtcbiAgICAgIHRocm93IGVycm9yO1xuICAgIH0pO1xuICAgIHJldHVybiB0aGlzLmNvbm5lY3Rpbmc7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGNvbm5lY3RXaXRoRmFsbGJhY2soKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMuY29ubmVjdEhvc3QodGhpcy5vcHRpb25zLmhvc3QpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoIXNob3VsZFJlc29sdmVQdWJsaWNHYXRld2F5KHRoaXMub3B0aW9ucy5ob3N0LCBlcnJvcikpIHRocm93IGVycm9yO1xuICAgICAgY29uc3QgcmVzb2x2ZUFkZHJlc3NlcyA9IHRoaXMub3B0aW9ucy5yZXNvbHZlUHVibGljQWRkcmVzc2VzID8/IHJlc29sdmVQdWJsaWNHYXRld2F5QWRkcmVzc2VzO1xuICAgICAgbGV0IGFkZHJlc3Nlczogc3RyaW5nW107XG4gICAgICB0cnkge1xuICAgICAgICBhZGRyZXNzZXMgPSBhd2FpdCByZXNvbHZlQWRkcmVzc2VzKHRoaXMub3B0aW9ucy5ob3N0KTtcbiAgICAgIH0gY2F0Y2ggKHJlc29sdmVFcnJvcikge1xuICAgICAgICBsb2dnZXIud2FybihcInB1YmxpYyBMYWtlYm94IGdhdGV3YXkgcmVzb2x1dGlvbiBmYWlsZWRcIiwge1xuICAgICAgICAgIGhvc3Q6IHRoaXMub3B0aW9ucy5ob3N0LFxuICAgICAgICAgIGVycm9yOiBlcnJvclV0aWxzLnRvRXJyb3IocmVzb2x2ZUVycm9yKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgICAgbG9nZ2VyLndhcm4oXCJwcml2YXRlIExha2Vib3ggZ2F0ZXdheSB1bnJlYWNoYWJsZTsgcmV0cnlpbmcgcHVibGljIGFkZHJlc3Nlc1wiLCB7XG4gICAgICAgIGhvc3Q6IHRoaXMub3B0aW9ucy5ob3N0LFxuICAgICAgICBhZGRyZXNzQ291bnQ6IGFkZHJlc3Nlcy5sZW5ndGgsXG4gICAgICB9KTtcbiAgICAgIGxldCBsYXN0RXJyb3I6IHVua25vd24gPSBlcnJvcjtcbiAgICAgIGZvciAoY29uc3QgYWRkcmVzcyBvZiBhZGRyZXNzZXMpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCB0aGlzLmNvbm5lY3RIb3N0KGFkZHJlc3MpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfSBjYXRjaCAoY29ubmVjdEVycm9yKSB7XG4gICAgICAgICAgbGFzdEVycm9yID0gY29ubmVjdEVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aHJvdyBsYXN0RXJyb3I7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBjb25uZWN0SG9zdChjb25uZWN0SG9zdDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMuY2xvc2VkKSB0aHJvdyBuZXcgRXJyb3IoXCJTU0ggc2Vzc2lvbiBpcyBjbG9zZWRcIik7XG4gICAgY29uc3QgY2xpZW50ID0gYXdhaXQgdGhpcy5jcmVhdGVWZXJpZmllZENsaWVudChjb25uZWN0SG9zdCwgdHJ1ZSk7XG4gICAgaWYgKHRoaXMuY2xvc2VkKSB7XG4gICAgICBjbGllbnQuZGVzdHJveSgpO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU1NIIHNlc3Npb24gaXMgY2xvc2VkXCIpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgY29uc3QgdHJhbnNwb3J0ID0gYXdhaXQgY3JlYXRlU3NoVHJhbnNwb3J0KHtcbiAgICAgICAgaG9zdDogdGhpcy5vcHRpb25zLmhvc3QsXG4gICAgICAgIGNvbm5lY3RIb3N0LFxuICAgICAgICBwb3J0OiB0aGlzLm9wdGlvbnMucG9ydCxcbiAgICAgICAgdXNlcm5hbWU6IHRoaXMub3B0aW9ucy51c2VybmFtZSxcbiAgICAgICAgcHJpdmF0ZUtleVBhdGg6IHRoaXMub3B0aW9ucy5wcml2YXRlS2V5UGF0aCxcbiAgICAgICAga25vd25Ib3N0c1BhdGg6IHRoaXMub3B0aW9ucy5rbm93bkhvc3RzUGF0aCxcbiAgICAgICAgY29ubmVjdFRpbWVvdXRNczogdGhpcy5vcHRpb25zLmNvbm5lY3RUaW1lb3V0TXMsXG4gICAgICAgIHNzaDJDbGllbnQ6IGNsaWVudCxcbiAgICAgICAgY3JlYXRlU3NoMkNvbW1hbmRDbGllbnQ6ICgpID0+IHRoaXMuY3JlYXRlVmVyaWZpZWRDbGllbnQoY29ubmVjdEhvc3QsIGZhbHNlKSxcbiAgICAgICAgdHJhbnNwb3J0OiB0aGlzLm9wdGlvbnMuc3NoVHJhbnNwb3J0LFxuICAgICAgICBzc2gyUGF0Y2g6IHRoaXMub3B0aW9ucy5zc2gyUGF0Y2gsXG4gICAgICAgIC4uLih0aGlzLm9wdGlvbnMuc3NoQ29tbWFuZCA/IHsgc3NoQ29tbWFuZDogdGhpcy5vcHRpb25zLnNzaENvbW1hbmQgfSA6IHt9KSxcbiAgICAgIH0pO1xuICAgICAgaWYgKHRoaXMuY2xvc2VkKSB7XG4gICAgICAgIGF3YWl0IHRyYW5zcG9ydC5jbG9zZSgpO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTU0ggc2Vzc2lvbiBpcyBjbG9zZWRcIik7XG4gICAgICB9XG4gICAgICB0aGlzLnRyYW5zcG9ydCA9IHRyYW5zcG9ydDtcbiAgICAgIHRoaXMuY29ubmVjdGluZyA9IHVuZGVmaW5lZDtcbiAgICAgIGlmICh0cmFuc3BvcnQua2luZCA9PT0gXCJvcGVuc3NoXCIpIGNsaWVudC5kZXN0cm95KCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNsaWVudC5kZXN0cm95KCk7XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZVZlcmlmaWVkQ2xpZW50KGNvbm5lY3RIb3N0OiBzdHJpbmcsIHJlbWVtYmVySG9zdDogYm9vbGVhbik6IFByb21pc2U8U3NoMkNsaWVudD4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBpZiAodGhpcy5jbG9zZWQpIHtcbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihcIlNTSCBzZXNzaW9uIGlzIGNsb3NlZFwiKSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGNsaWVudCA9IG5ldyBDbGllbnQoKTtcbiAgICAgIHRoaXMucGVuZGluZ0NsaWVudHMuYWRkKGNsaWVudCk7XG4gICAgICBsZXQgdmVyaWZpZWRIb3N0OiB7IGZpbmdlcnByaW50OiBzdHJpbmc7IGtleTogQnVmZmVyIH0gfCB1bmRlZmluZWQ7XG4gICAgICBsZXQgc2V0dGxlZCA9IGZhbHNlO1xuICAgICAgY29uc3QgZmluaXNoU2V0dGxlbWVudCA9ICgpID0+IHtcbiAgICAgICAgdGhpcy5wZW5kaW5nQ2xpZW50cy5kZWxldGUoY2xpZW50KTtcbiAgICAgIH07XG4gICAgICBjbGllbnQub25jZShcInJlYWR5XCIsICgpID0+IHtcbiAgICAgICAgY29uc3QgZmluaXNoID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICAgIGlmICghdmVyaWZpZWRIb3N0KSB0aHJvdyBuZXcgRXJyb3IoXCJTU0ggZ2F0ZXdheSBkaWQgbm90IHByb3ZpZGUgYSB2ZXJpZmllZCBob3N0IGtleVwiKTtcbiAgICAgICAgICB0aGlzLmtub3duSG9zdCA9IHZlcmlmaWVkSG9zdC5maW5nZXJwcmludDtcbiAgICAgICAgICBpZiAocmVtZW1iZXJIb3N0KSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLm9wdGlvbnMucmVtZW1iZXJIb3N0Py4odmVyaWZpZWRIb3N0LmZpbmdlcnByaW50LCB2ZXJpZmllZEhvc3Qua2V5KTtcbiAgICAgICAgICB9XG4gICAgICAgICAgc2V0dGxlZCA9IHRydWU7XG4gICAgICAgICAgZmluaXNoU2V0dGxlbWVudCgpO1xuICAgICAgICAgIHJlc29sdmUoY2xpZW50KTtcbiAgICAgICAgfTtcbiAgICAgICAgdm9pZCBmaW5pc2goKS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgICBjbGllbnQuZGVzdHJveSgpO1xuICAgICAgICAgIGlmIChzZXR0bGVkKSByZXR1cm47XG4gICAgICAgICAgc2V0dGxlZCA9IHRydWU7XG4gICAgICAgICAgZmluaXNoU2V0dGxlbWVudCgpO1xuICAgICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgICBjbGllbnQub25jZShcImVycm9yXCIsIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoc2V0dGxlZCkgcmV0dXJuO1xuICAgICAgICBzZXR0bGVkID0gdHJ1ZTtcbiAgICAgICAgZmluaXNoU2V0dGxlbWVudCgpO1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSk7XG4gICAgICBjbGllbnQub25jZShcImNsb3NlXCIsICgpID0+IHtcbiAgICAgICAgaWYgKHNldHRsZWQpIHJldHVybjtcbiAgICAgICAgc2V0dGxlZCA9IHRydWU7XG4gICAgICAgIGZpbmlzaFNldHRsZW1lbnQoKTtcbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihcIlNTSCBnYXRld2F5IGNsb3NlZCBiZWZvcmUgYXV0aGVudGljYXRpb24gY29tcGxldGVkXCIpKTtcbiAgICAgIH0pO1xuICAgICAgdHJ5IHtcbiAgICAgICAgY2xpZW50LmNvbm5lY3Qoe1xuICAgICAgICAgIGhvc3Q6IGNvbm5lY3RIb3N0LFxuICAgICAgICAgIHBvcnQ6IHRoaXMub3B0aW9ucy5wb3J0LFxuICAgICAgICAgIHVzZXJuYW1lOiB0aGlzLm9wdGlvbnMudXNlcm5hbWUsXG4gICAgICAgICAgcHJpdmF0ZUtleTogdGhpcy5vcHRpb25zLnByaXZhdGVLZXksXG4gICAgICAgICAgcmVhZHlUaW1lb3V0OiB0aGlzLm9wdGlvbnMuY29ubmVjdFRpbWVvdXRNcyxcbiAgICAgICAgICBrZWVwYWxpdmVJbnRlcnZhbDogMTVfMDAwLFxuICAgICAgICAgIGtlZXBhbGl2ZUNvdW50TWF4OiAzLFxuICAgICAgICAgIGhvc3RWZXJpZmllcjogKGtleTogQnVmZmVyKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBmaW5nZXJwcmludCA9IGNyZWF0ZUhhc2goXCJzaGEyNTZcIikudXBkYXRlKGtleSkuZGlnZXN0KFwiYmFzZTY0XCIpO1xuICAgICAgICAgICAgaWYgKHRoaXMua25vd25Ib3N0ICYmIGZpbmdlcnByaW50ICE9PSB0aGlzLmtub3duSG9zdCkgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgdmVyaWZpZWRIb3N0ID0geyBmaW5nZXJwcmludCwga2V5OiBCdWZmZXIuZnJvbShrZXkpIH07XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICB9LFxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHNldHRsZWQgPSB0cnVlO1xuICAgICAgICBmaW5pc2hTZXR0bGVtZW50KCk7XG4gICAgICAgIGNsaWVudC5kZXN0cm95KCk7XG4gICAgICAgIHJlamVjdChlcnJvcik7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogU3RhcnRzIG9uZSBjb21tYW5kIGFzIGEgTGFrZWJveCB1c2VyIGFuZCByZXR1cm5zIGl0cyBsaXZlIG91dHB1dCBhbmRcbiAgICogY29tcGxldGlvbiBzdGF0ZSBpbW1lZGlhdGVseS5cbiAgICovXG4gIGV4ZWN1dGUoXG4gICAgY29tbWFuZDogc3RyaW5nLFxuICAgIGFyZ3M6IHN0cmluZ1tdLFxuICAgIG9wdGlvbnM6IHtcbiAgICAgIHVzZXI6IHsgbmFtZTogc3RyaW5nOyBob21lOiBzdHJpbmcgfTtcbiAgICAgIGN3ZD86IHN0cmluZztcbiAgICAgIGVudj86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG4gICAgICB0aW1lb3V0TXM6IG51bWJlcjtcbiAgICAgIHNpZ25hbD86IEFib3J0U2lnbmFsO1xuICAgIH0sXG4gICk6IFNzaENvbW1hbmQge1xuICAgIGNvbnN0IHsgdXNlciwgLi4ucmVzdCB9ID0gb3B0aW9ucztcbiAgICByZXR1cm4gdGhpcy5zdGFydENvbW1hbmQoY29tbWFuZCwgYXJncywgcmVzdCwgeyBraW5kOiBcInVzZXJcIiwgLi4udXNlciB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAaW50ZXJuYWwgU3RhcnRzIG9uZSBmaXhlZCBwYWNrYWdlLW93bmVkIGJvb3RzdHJhcCBjb21tYW5kIGFzIHJvb3QuXG4gICAqXG4gICAqIE5ldmVyIHJvdXRlIFJFU1QsIGFnZW50LXRvb2wsIHNlcnZpY2UsIG9yIGVudmlyb25tZW50IGlucHV0IGhlcmUuXG4gICAqL1xuICBleGVjdXRlUHJpdmlsZWdlZChcbiAgICBjb21tYW5kOiBzdHJpbmcsXG4gICAgYXJnczogc3RyaW5nW10sXG4gICAgb3B0aW9uczogeyB0aW1lb3V0TXM6IG51bWJlcjsgc2lnbmFsPzogQWJvcnRTaWduYWwgfSxcbiAgKTogU3NoQ29tbWFuZCB7XG4gICAgcmV0dXJuIHRoaXMuc3RhcnRDb21tYW5kKGNvbW1hbmQsIGFyZ3MsIG9wdGlvbnMsIHsga2luZDogXCJyb290XCIgfSk7XG4gIH1cblxuICBwcml2YXRlIHN0YXJ0Q29tbWFuZChcbiAgICBjb21tYW5kOiBzdHJpbmcsXG4gICAgYXJnczogc3RyaW5nW10sXG4gICAgb3B0aW9uczoge1xuICAgICAgY3dkPzogc3RyaW5nO1xuICAgICAgZW52PzogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbiAgICAgIHRpbWVvdXRNczogbnVtYmVyO1xuICAgICAgc2lnbmFsPzogQWJvcnRTaWduYWw7XG4gICAgfSxcbiAgICBpZGVudGl0eTogU3NoQ29tbWFuZElkZW50aXR5LFxuICApOiBTc2hDb21tYW5kIHtcbiAgICBjb25zdCBzY3JpcHQgPSBzc2hDb21tYW5kU2NyaXB0KGNvbW1hbmQsIGFyZ3MsIG9wdGlvbnMuY3dkLCBvcHRpb25zLmVudiwgaWRlbnRpdHkpO1xuICAgIGNvbnN0IHNzaENvbW1hbmQgPSBuZXcgU3NoQ29tbWFuZChjb21tYW5kLCBhcmdzLCBvcHRpb25zLCBhc3luYyAoZXhlY3V0aW9uKSA9PiB7XG4gICAgICBhd2FpdCB0aGlzLmNvbm5lY3QoKTtcbiAgICAgIGlmIChleGVjdXRpb24uc2lnbmFsLmFib3J0ZWQpIHJldHVybiAxMzA7XG4gICAgICBjb25zdCB0cmFuc3BvcnQgPSB0aGlzLnRyYW5zcG9ydDtcbiAgICAgIGlmICghdHJhbnNwb3J0KSB0aHJvdyBuZXcgRXJyb3IoXCJTU0ggdHJhbnNwb3J0IGRpZCBub3QgaW5pdGlhbGl6ZVwiKTtcbiAgICAgIHJldHVybiB0cmFuc3BvcnQucnVuKHNjcmlwdCwgZXhlY3V0aW9uKTtcbiAgICB9KTtcbiAgICB0aGlzLmFjdGl2ZUNvbW1hbmRzLmFkZChzc2hDb21tYW5kKTtcbiAgICBjb25zdCByZW1vdmUgPSAoKSA9PiB0aGlzLmFjdGl2ZUNvbW1hbmRzLmRlbGV0ZShzc2hDb21tYW5kKTtcbiAgICB2b2lkIHNzaENvbW1hbmQucmVzdWx0LnRoZW4ocmVtb3ZlLCByZW1vdmUpO1xuICAgIHJldHVybiBzc2hDb21tYW5kO1xuICB9XG5cbiAgLyoqIE9wZW5zIGEgcmVtb3RlIFRDUCBjb25uZWN0aW9uIHRocm91Z2ggbmF0aXZlIFNPQ0tTNSBvciBzc2gyIGRpcmVjdCBmb3J3YXJkaW5nLiAqL1xuICBhc3luYyBmb3J3YXJkT3V0KHJlbW90ZUhvc3Q6IHN0cmluZywgcmVtb3RlUG9ydDogbnVtYmVyKTogUHJvbWlzZTxEdXBsZXg+IHtcbiAgICBhd2FpdCB0aGlzLmNvbm5lY3QoKTtcbiAgICBjb25zdCB0cmFuc3BvcnQgPSB0aGlzLnRyYW5zcG9ydDtcbiAgICBpZiAoIXRyYW5zcG9ydCkgdGhyb3cgbmV3IEVycm9yKFwiU1NIIHRyYW5zcG9ydCBkaWQgbm90IGluaXRpYWxpemVcIik7XG4gICAgcmV0dXJuIHRyYW5zcG9ydC5jb25uZWN0KHJlbW90ZUhvc3QsIHJlbW90ZVBvcnQpO1xuICB9XG5cbiAgLyoqIENhbmNlbHMgYWN0aXZlIGNvbW1hbmRzLCBjbG9zZXMgdGhlIHNlbGVjdGVkIHRyYW5zcG9ydCwgYW5kIGNsZWFycyBjb25uZWN0aW9uIHN0YXRlLiAqL1xuICBjbG9zZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5jbG9zaW5nKSByZXR1cm4gdGhpcy5jbG9zaW5nO1xuICAgIHRoaXMuY2xvc2VkID0gdHJ1ZTtcbiAgICB0aGlzLmNsb3NpbmcgPSB0aGlzLmNsb3NlUmVzb3VyY2VzKCk7XG4gICAgcmV0dXJuIHRoaXMuY2xvc2luZztcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY2xvc2VSZXNvdXJjZXMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgY2FuY2VsbGF0aW9ucyA9IFsuLi50aGlzLmFjdGl2ZUNvbW1hbmRzXS5tYXAoKGNvbW1hbmQpID0+IGNvbW1hbmQuY2FuY2VsKCkpO1xuICAgIHRoaXMuYWN0aXZlQ29tbWFuZHMuY2xlYXIoKTtcbiAgICBmb3IgKGNvbnN0IGNsaWVudCBvZiB0aGlzLnBlbmRpbmdDbGllbnRzKSBjbGllbnQuZGVzdHJveSgpO1xuICAgIHRoaXMucGVuZGluZ0NsaWVudHMuY2xlYXIoKTtcbiAgICBjb25zdCB0cmFuc3BvcnQgPSB0aGlzLnRyYW5zcG9ydDtcbiAgICBjb25zdCBjb25uZWN0aW5nID0gdGhpcy5jb25uZWN0aW5nO1xuICAgIHRoaXMudHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuY29ubmVjdGluZyA9IHVuZGVmaW5lZDtcbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKFtcbiAgICAgIC4uLmNhbmNlbGxhdGlvbnMsXG4gICAgICAuLi4odHJhbnNwb3J0ID8gW3RyYW5zcG9ydC5jbG9zZSgpXSA6IFtdKSxcbiAgICAgIC4uLihjb25uZWN0aW5nID8gW2Nvbm5lY3RpbmddIDogW10pLFxuICAgIF0pO1xuICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIHJlc3VsdHMpIHtcbiAgICAgIGlmIChyZXN1bHQuc3RhdHVzID09PSBcInJlamVjdGVkXCIpIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oXCJmYWlsZWQgdG8gY2xvc2UgU1NIIHNlc3Npb24gcmVzb3VyY2VcIiwge1xuICAgICAgICAgIGVycm9yOiBlcnJvclV0aWxzLnRvRXJyb3IocmVzdWx0LnJlYXNvbiksXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFJlc29sdmVzIHB1YmxpYyBJUHY0IGFkZHJlc3NlcyBmb3IgYSBEYXRhYnJpY2tzIHNlcnZpY2UtZGlyZWN0IGdhdGV3YXkuXG4gKlxuICogUmV0dXJucyBhbiBlbXB0eSBsaXN0IGZvciBvdGhlciBob3N0bmFtZXMuIEROUy1vdmVyLUhUVFBTIHJlcXVlc3RzIHRpbWUgb3V0XG4gKiBhZnRlciBmaXZlIHNlY29uZHMgYW5kIHJlamVjdCBpbnZhbGlkIHJlc3BvbnNlcy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlc29sdmVQdWJsaWNHYXRld2F5QWRkcmVzc2VzKFxuICBob3N0OiBzdHJpbmcsXG4gIGZldGNoZXI6IHR5cGVvZiBmZXRjaCA9IGZldGNoLFxuKTogUHJvbWlzZTxzdHJpbmdbXT4ge1xuICBpZiAoIWhvc3QudG9Mb3dlckNhc2UoKS5lbmRzV2l0aChTRVJWSUNFX0RJUkVDVF9TVUZGSVgpKSByZXR1cm4gW107XG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2hlcihcbiAgICBgaHR0cHM6Ly9kbnMuZ29vZ2xlL3Jlc29sdmU/bmFtZT0ke2VuY29kZVVSSUNvbXBvbmVudChob3N0KX0mdHlwZT1BYCxcbiAgICB7IGhlYWRlcnM6IHsgQWNjZXB0OiBcImFwcGxpY2F0aW9uL2Rucy1qc29uXCIgfSwgc2lnbmFsOiBBYm9ydFNpZ25hbC50aW1lb3V0KDVfMDAwKSB9LFxuICApO1xuICBpZiAoIXJlc3BvbnNlLm9rKSB0aHJvdyBuZXcgRXJyb3IoYFB1YmxpYyBETlMgcmVzb2x1dGlvbiBmYWlsZWQgKCR7cmVzcG9uc2Uuc3RhdHVzfSlgKTtcbiAgY29uc3QgcGF5bG9hZCA9IERuc1Jlc3BvbnNlU2NoZW1hLnBhcnNlKGF3YWl0IHJlc3BvbnNlLmpzb24oKSk7XG4gIHJldHVybiBbXG4gICAgLi4ubmV3IFNldChcbiAgICAgIChwYXlsb2FkLkFuc3dlciA/PyBbXSlcbiAgICAgICAgLmZpbHRlcigoYW5zd2VyKSA9PiBhbnN3ZXIudHlwZSA9PT0gMSAmJiBpc0lQKGFuc3dlci5kYXRhKSA9PT0gNClcbiAgICAgICAgLm1hcCgoYW5zd2VyKSA9PiBhbnN3ZXIuZGF0YSksXG4gICAgKSxcbiAgXTtcbn1cblxuZnVuY3Rpb24gc2hvdWxkUmVzb2x2ZVB1YmxpY0dhdGV3YXkoaG9zdDogc3RyaW5nLCBlcnJvcjogdW5rbm93bik6IGJvb2xlYW4ge1xuICBpZiAoIWhvc3QudG9Mb3dlckNhc2UoKS5lbmRzV2l0aChTRVJWSUNFX0RJUkVDVF9TVUZGSVgpKSByZXR1cm4gZmFsc2U7XG4gIGNvbnN0IGNvZGUgPVxuICAgIChlcnJvciBhcyB7IGNvZGU/OiB1bmtub3duOyBjYXVzZT86IHsgY29kZT86IHVua25vd24gfSB9KT8uY29kZSA/P1xuICAgIChlcnJvciBhcyB7IGNhdXNlPzogeyBjb2RlPzogdW5rbm93biB9IH0pPy5jYXVzZT8uY29kZTtcbiAgcmV0dXJuIGNvZGUgPT09IFwiRUhPU1RVTlJFQUNIXCIgfHwgY29kZSA9PT0gXCJFTkVUVU5SRUFDSFwiIHx8IGNvZGUgPT09IFwiRVRJTUVET1VUXCI7XG59XG4iXX0=
@@ -0,0 +1,15 @@
1
+ import { z } from "zod";
2
+ export declare const SshTransportModeSchema: z.ZodDefault<z.ZodPipe<z.ZodString, z.ZodEnum<{
3
+ auto: "auto";
4
+ openssh: "openssh";
5
+ ssh2: "ssh2";
6
+ }>>>;
7
+ /** SSH transport selected for a Lakebox session. */
8
+ export type SshTransportMode = z.output<typeof SshTransportModeSchema>;
9
+ export declare const Ssh2PatchModeSchema: z.ZodDefault<z.ZodPipe<z.ZodString, z.ZodEnum<{
10
+ true: "true";
11
+ false: "false";
12
+ auto: "auto";
13
+ }>>>;
14
+ /** Missing exec-reply patch policy applied when ssh2 is selected. */
15
+ export type Ssh2PatchMode = z.output<typeof Ssh2PatchModeSchema>;
@@ -0,0 +1,16 @@
1
+ import { z } from "zod";
2
+ export const SshTransportModeSchema = z
3
+ .string()
4
+ .trim()
5
+ .toLowerCase()
6
+ .pipe(z.enum(["auto", "openssh", "ssh2"]))
7
+ .default("auto")
8
+ .describe("SSH transport: auto prefers native OpenSSH with SOCKS5 forwarding and otherwise selects ssh2; explicit modes never switch.");
9
+ export const Ssh2PatchModeSchema = z
10
+ .string()
11
+ .trim()
12
+ .toLowerCase()
13
+ .pipe(z.enum(["auto", "true", "false"]))
14
+ .default("auto")
15
+ .describe("ssh2 missing-exec-reply workaround: auto patches only in development, true requires it, false never patches.");
16
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNwb3J0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3RyYW5zcG9ydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsQ0FBQyxFQUFFLE1BQU0sS0FBSyxDQUFDO0FBRXhCLE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFHLENBQUM7S0FDcEMsTUFBTSxFQUFFO0tBQ1IsSUFBSSxFQUFFO0tBQ04sV0FBVyxFQUFFO0tBQ2IsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7S0FDekMsT0FBTyxDQUFDLE1BQU0sQ0FBQztLQUNmLFFBQVEsQ0FDUCw0SEFBNEgsQ0FDN0gsQ0FBQztBQUlKLE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLENBQUM7S0FDakMsTUFBTSxFQUFFO0tBQ1IsSUFBSSxFQUFFO0tBQ04sV0FBVyxFQUFFO0tBQ2IsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7S0FDdkMsT0FBTyxDQUFDLE1BQU0sQ0FBQztLQUNmLFFBQVEsQ0FDUCw4R0FBOEcsQ0FDL0csQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5cbmV4cG9ydCBjb25zdCBTc2hUcmFuc3BvcnRNb2RlU2NoZW1hID0gelxuICAuc3RyaW5nKClcbiAgLnRyaW0oKVxuICAudG9Mb3dlckNhc2UoKVxuICAucGlwZSh6LmVudW0oW1wiYXV0b1wiLCBcIm9wZW5zc2hcIiwgXCJzc2gyXCJdKSlcbiAgLmRlZmF1bHQoXCJhdXRvXCIpXG4gIC5kZXNjcmliZShcbiAgICBcIlNTSCB0cmFuc3BvcnQ6IGF1dG8gcHJlZmVycyBuYXRpdmUgT3BlblNTSCB3aXRoIFNPQ0tTNSBmb3J3YXJkaW5nIGFuZCBvdGhlcndpc2Ugc2VsZWN0cyBzc2gyOyBleHBsaWNpdCBtb2RlcyBuZXZlciBzd2l0Y2guXCIsXG4gICk7XG4vKiogU1NIIHRyYW5zcG9ydCBzZWxlY3RlZCBmb3IgYSBMYWtlYm94IHNlc3Npb24uICovXG5leHBvcnQgdHlwZSBTc2hUcmFuc3BvcnRNb2RlID0gei5vdXRwdXQ8dHlwZW9mIFNzaFRyYW5zcG9ydE1vZGVTY2hlbWE+O1xuXG5leHBvcnQgY29uc3QgU3NoMlBhdGNoTW9kZVNjaGVtYSA9IHpcbiAgLnN0cmluZygpXG4gIC50cmltKClcbiAgLnRvTG93ZXJDYXNlKClcbiAgLnBpcGUoei5lbnVtKFtcImF1dG9cIiwgXCJ0cnVlXCIsIFwiZmFsc2VcIl0pKVxuICAuZGVmYXVsdChcImF1dG9cIilcbiAgLmRlc2NyaWJlKFxuICAgIFwic3NoMiBtaXNzaW5nLWV4ZWMtcmVwbHkgd29ya2Fyb3VuZDogYXV0byBwYXRjaGVzIG9ubHkgaW4gZGV2ZWxvcG1lbnQsIHRydWUgcmVxdWlyZXMgaXQsIGZhbHNlIG5ldmVyIHBhdGNoZXMuXCIsXG4gICk7XG4vKiogTWlzc2luZyBleGVjLXJlcGx5IHBhdGNoIHBvbGljeSBhcHBsaWVkIHdoZW4gc3NoMiBpcyBzZWxlY3RlZC4gKi9cbmV4cG9ydCB0eXBlIFNzaDJQYXRjaE1vZGUgPSB6Lm91dHB1dDx0eXBlb2YgU3NoMlBhdGNoTW9kZVNjaGVtYT47XG4iXX0=
@@ -0,0 +1 @@
1
+ {"root":["../src/_ssh.ts","../src/_ssh_openssh.ts","../src/_ssh_ssh2.ts","../src/key-store.ts","../src/lifecycle.ts","../src/rest.ts","../src/session.ts","../src/transport.ts","../index.ts"],"version":"5.9.3"}
package/package.json CHANGED
@@ -1,6 +1,119 @@
1
1
  {
2
2
  "name": "@dbx-tools/lakebox",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "description": "Databricks Lakebox REST, pooled SSH transport, and deterministic user routing",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/reggie-db/dbx-tools.git",
7
+ "directory": "packages/js/node/lakebox"
8
+ },
9
+ "scripts": {
10
+ "build": "projen build",
11
+ "compile": "projen compile",
12
+ "default": "projen default",
13
+ "package": "projen package",
14
+ "post-compile": "projen post-compile",
15
+ "pre-compile": "projen pre-compile",
16
+ "prepack": "projen prepack",
17
+ "test": "projen test",
18
+ "watch": "projen watch",
19
+ "projen": "projen"
20
+ },
21
+ "devDependencies": {
22
+ "@types/node": "^24.6.0",
23
+ "@types/ssh2": "^1",
24
+ "typescript": "^5.9.3",
25
+ "vitest": "3.2.4"
26
+ },
27
+ "dependencies": {
28
+ "@dbx-tools/core": "^0.9.132",
29
+ "@dbx-tools/shared-core": "^0.9.132",
30
+ "@dbx-tools/shared-lakebox": "^0.9.132",
31
+ "generic-pool": "^3.9.0",
32
+ "socks": "^2.8.10",
33
+ "ssh2": "^1.17.0",
34
+ "zod": "4.3.6"
35
+ },
36
+ "main": "./lib/index.js",
37
+ "license": "Apache-2.0",
38
+ "publishConfig": {
39
+ "access": "public",
40
+ "main": "./lib/index.js",
41
+ "types": "./lib/index.d.ts",
42
+ "exports": {
43
+ ".": {
44
+ "types": "./lib/index.d.ts",
45
+ "default": "./lib/index.js"
46
+ },
47
+ "./key-store": {
48
+ "types": "./lib/src/key-store.d.ts",
49
+ "default": "./lib/src/key-store.js"
50
+ },
51
+ "./lifecycle": {
52
+ "types": "./lib/src/lifecycle.d.ts",
53
+ "default": "./lib/src/lifecycle.js"
54
+ },
55
+ "./rest": {
56
+ "types": "./lib/src/rest.d.ts",
57
+ "default": "./lib/src/rest.js"
58
+ },
59
+ "./session": {
60
+ "types": "./lib/src/session.d.ts",
61
+ "default": "./lib/src/session.js"
62
+ },
63
+ "./transport": {
64
+ "types": "./lib/src/transport.d.ts",
65
+ "default": "./lib/src/transport.js"
66
+ },
67
+ "./*": {
68
+ "types": "./lib/src/*/index.d.ts",
69
+ "default": "./lib/src/*/index.js"
70
+ },
71
+ "./package.json": "./package.json"
72
+ }
73
+ },
74
+ "version": "0.9.132",
75
+ "types": "./lib/index.d.ts",
76
+ "dbxToolsConfig": {
77
+ "tags": [
78
+ "node"
79
+ ]
80
+ },
81
+ "type": "module",
82
+ "exports": {
83
+ ".": {
84
+ "types": "./lib/index.d.ts",
85
+ "default": "./lib/index.js"
86
+ },
87
+ "./key-store": {
88
+ "types": "./lib/src/key-store.d.ts",
89
+ "default": "./lib/src/key-store.js"
90
+ },
91
+ "./lifecycle": {
92
+ "types": "./lib/src/lifecycle.d.ts",
93
+ "default": "./lib/src/lifecycle.js"
94
+ },
95
+ "./rest": {
96
+ "types": "./lib/src/rest.d.ts",
97
+ "default": "./lib/src/rest.js"
98
+ },
99
+ "./session": {
100
+ "types": "./lib/src/session.d.ts",
101
+ "default": "./lib/src/session.js"
102
+ },
103
+ "./transport": {
104
+ "types": "./lib/src/transport.d.ts",
105
+ "default": "./lib/src/transport.js"
106
+ },
107
+ "./*": {
108
+ "types": "./lib/src/*/index.d.ts",
109
+ "default": "./lib/src/*/index.js"
110
+ },
111
+ "./package.json": "./package.json"
112
+ },
113
+ "files": [
114
+ "index.ts",
115
+ "src",
116
+ "lib"
117
+ ],
118
+ "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"bunx projen\"."
119
+ }