@milaboratories/pl-deployments 2.15.7 → 2.15.9

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.
Files changed (106) hide show
  1. package/README.md +18 -5
  2. package/dist/common/os_and_arch.cjs +19 -19
  3. package/dist/common/os_and_arch.cjs.map +1 -1
  4. package/dist/common/os_and_arch.js +19 -19
  5. package/dist/common/os_and_arch.js.map +1 -1
  6. package/dist/common/pl_binary.cjs +9 -9
  7. package/dist/common/pl_binary.cjs.map +1 -1
  8. package/dist/common/pl_binary.d.ts +6 -6
  9. package/dist/common/pl_binary.d.ts.map +1 -1
  10. package/dist/common/pl_binary.js +9 -9
  11. package/dist/common/pl_binary.js.map +1 -1
  12. package/dist/common/pl_binary_download.cjs +16 -16
  13. package/dist/common/pl_binary_download.cjs.map +1 -1
  14. package/dist/common/pl_binary_download.d.ts +6 -6
  15. package/dist/common/pl_binary_download.d.ts.map +1 -1
  16. package/dist/common/pl_binary_download.js +16 -16
  17. package/dist/common/pl_binary_download.js.map +1 -1
  18. package/dist/common/pl_version.cjs +1 -1
  19. package/dist/common/pl_version.cjs.map +1 -1
  20. package/dist/common/pl_version.js +1 -1
  21. package/dist/common/pl_version.js.map +1 -1
  22. package/dist/index.d.ts +5 -5
  23. package/dist/local/options.d.ts +4 -4
  24. package/dist/local/pid.cjs +1 -1
  25. package/dist/local/pid.cjs.map +1 -1
  26. package/dist/local/pid.js +1 -1
  27. package/dist/local/pid.js.map +1 -1
  28. package/dist/local/pl.cjs +26 -26
  29. package/dist/local/pl.cjs.map +1 -1
  30. package/dist/local/pl.d.ts +8 -8
  31. package/dist/local/pl.d.ts.map +1 -1
  32. package/dist/local/pl.js +26 -26
  33. package/dist/local/pl.js.map +1 -1
  34. package/dist/local/process.cjs +16 -16
  35. package/dist/local/process.cjs.map +1 -1
  36. package/dist/local/process.d.ts +2 -2
  37. package/dist/local/process.js +16 -16
  38. package/dist/local/process.js.map +1 -1
  39. package/dist/local/trace.cjs.map +1 -1
  40. package/dist/local/trace.d.ts +1 -1
  41. package/dist/local/trace.js.map +1 -1
  42. package/dist/package.json.cjs +2 -1
  43. package/dist/package.json.cjs.map +1 -1
  44. package/dist/package.json.js +2 -1
  45. package/dist/package.json.js.map +1 -1
  46. package/dist/ssh/__tests__/common-utils.d.ts +2 -2
  47. package/dist/ssh/__tests__/common-utils.d.ts.map +1 -1
  48. package/dist/ssh/connection_info.cjs +13 -7
  49. package/dist/ssh/connection_info.cjs.map +1 -1
  50. package/dist/ssh/connection_info.d.ts +1 -1
  51. package/dist/ssh/connection_info.d.ts.map +1 -1
  52. package/dist/ssh/connection_info.js +13 -7
  53. package/dist/ssh/connection_info.js.map +1 -1
  54. package/dist/ssh/pl.cjs +79 -76
  55. package/dist/ssh/pl.cjs.map +1 -1
  56. package/dist/ssh/pl.d.ts +18 -18
  57. package/dist/ssh/pl.d.ts.map +1 -1
  58. package/dist/ssh/pl.js +79 -76
  59. package/dist/ssh/pl.js.map +1 -1
  60. package/dist/ssh/pl_paths.cjs +13 -13
  61. package/dist/ssh/pl_paths.cjs.map +1 -1
  62. package/dist/ssh/pl_paths.d.ts.map +1 -1
  63. package/dist/ssh/pl_paths.js +13 -13
  64. package/dist/ssh/pl_paths.js.map +1 -1
  65. package/dist/ssh/ssh.cjs +43 -40
  66. package/dist/ssh/ssh.cjs.map +1 -1
  67. package/dist/ssh/ssh.d.ts +9 -9
  68. package/dist/ssh/ssh.d.ts.map +1 -1
  69. package/dist/ssh/ssh.js +43 -40
  70. package/dist/ssh/ssh.js.map +1 -1
  71. package/dist/ssh/ssh_errors.cjs +7 -5
  72. package/dist/ssh/ssh_errors.cjs.map +1 -1
  73. package/dist/ssh/ssh_errors.d.ts.map +1 -1
  74. package/dist/ssh/ssh_errors.js +7 -5
  75. package/dist/ssh/ssh_errors.js.map +1 -1
  76. package/dist/ssh/supervisord.cjs +15 -13
  77. package/dist/ssh/supervisord.cjs.map +1 -1
  78. package/dist/ssh/supervisord.d.ts +2 -2
  79. package/dist/ssh/supervisord.d.ts.map +1 -1
  80. package/dist/ssh/supervisord.js +15 -13
  81. package/dist/ssh/supervisord.js.map +1 -1
  82. package/package.json +38 -37
  83. package/src/common/os_and_arch.ts +19 -19
  84. package/src/common/pl_binary.ts +30 -27
  85. package/src/common/pl_binary_download.ts +80 -59
  86. package/src/common/pl_version.ts +2 -2
  87. package/src/index.ts +5 -5
  88. package/src/local/config.test.yaml +19 -19
  89. package/src/local/options.ts +4 -4
  90. package/src/local/pid.ts +4 -4
  91. package/src/local/pl.test.ts +245 -253
  92. package/src/local/pl.ts +45 -50
  93. package/src/local/process.ts +21 -21
  94. package/src/local/trace.ts +1 -1
  95. package/src/ssh/__tests__/common-utils.ts +21 -19
  96. package/src/ssh/__tests__/pl-docker.test.ts +68 -59
  97. package/src/ssh/__tests__/ssh-docker.test.ts +152 -90
  98. package/src/ssh/__tests__/ssh-upload.test.ts +42 -31
  99. package/src/ssh/connection_info.ts +33 -27
  100. package/src/ssh/pl.test.ts +15 -13
  101. package/src/ssh/pl.ts +228 -143
  102. package/src/ssh/pl_paths.ts +22 -18
  103. package/src/ssh/ssh.ts +151 -74
  104. package/src/ssh/ssh_errors.test.ts +39 -39
  105. package/src/ssh/ssh_errors.ts +8 -6
  106. package/src/ssh/supervisord.ts +28 -28
package/dist/ssh/ssh.js CHANGED
@@ -65,18 +65,21 @@ class SshClient {
65
65
  if (err) {
66
66
  return reject(new Error(`ssh.exec: ${command}: ${err}`));
67
67
  }
68
- let stdout = '';
69
- let stderr = '';
70
- stream.on('close', (code) => {
68
+ let stdout = "";
69
+ let stderr = "";
70
+ stream
71
+ .on("close", (code) => {
71
72
  if (code === 0) {
72
73
  resolve({ stdout, stderr });
73
74
  }
74
75
  else {
75
76
  reject(new Error(`Command ${command} exited with code ${code}, stdout: ${stdout}, stderr: ${stderr}`));
76
77
  }
77
- }).on('data', (data) => {
78
+ })
79
+ .on("data", (data) => {
78
80
  stdout += data.toString();
79
- }).stderr.on('data', (data) => {
81
+ })
82
+ .stderr.on("data", (data) => {
80
83
  stderr += data.toString();
81
84
  });
82
85
  });
@@ -90,16 +93,16 @@ class SshClient {
90
93
  */
91
94
  static async getAuthTypes(host, port) {
92
95
  return new Promise((resolve) => {
93
- let stdout = '';
96
+ let stdout = "";
94
97
  const conn = new Client();
95
- conn.on('ready', () => {
98
+ conn.on("ready", () => {
96
99
  conn.end();
97
100
  const types = this.extractAuthMethods(stdout);
98
- resolve(types.length === 0 ? ['publickey', 'password'] : types);
101
+ resolve(types.length === 0 ? ["publickey", "password"] : types);
99
102
  });
100
- conn.on('error', () => {
103
+ conn.on("error", () => {
101
104
  conn.end();
102
- resolve(['publickey', 'password']);
105
+ resolve(["publickey", "password"]);
103
106
  });
104
107
  conn.connect({
105
108
  host,
@@ -118,7 +121,7 @@ class SshClient {
118
121
  */
119
122
  static extractAuthMethods(log) {
120
123
  const match = log.match(/Inbound: Received USERAUTH_FAILURE \((.+)\)/);
121
- return match && match[1] ? match[1].split(',').map((method) => method.trim()) : [];
124
+ return match && match[1] ? match[1].split(",").map((method) => method.trim()) : [];
122
125
  }
123
126
  /**
124
127
  * Sets up port forwarding between a remote port on the SSH server and a local port.
@@ -128,7 +131,7 @@ class SshClient {
128
131
  * @returns { server: net.Server } A promise resolving with the created server instance.
129
132
  */
130
133
  async forwardPort(ports, config) {
131
- const log = `ssh.forward:${ports.localPort}:${ports.remotePort}.id_${randomBytes(1).toString('hex')}`;
134
+ const log = `ssh.forward:${ports.localPort}:${ports.remotePort}.id_${randomBytes(1).toString("hex")}`;
132
135
  config = config ?? this.config;
133
136
  // we make this thing persistent so that if the connection
134
137
  // drops (it happened in the past because of lots of errors and forwardOut opened channels),
@@ -136,16 +139,16 @@ class SshClient {
136
139
  const persistentClient = new RetryablePromise((p) => {
137
140
  return new Promise((resolve, reject) => {
138
141
  const client = new Client();
139
- client.on('ready', () => {
142
+ client.on("ready", () => {
140
143
  this.logger.info(`${log}.client.ready`);
141
144
  resolve(client);
142
145
  });
143
- client.on('error', (err) => {
146
+ client.on("error", (err) => {
144
147
  this.logger.info(`${log}.client.error: ${err}`);
145
148
  p.reset();
146
149
  reject(err);
147
150
  });
148
- client.on('close', () => {
151
+ client.on("close", () => {
149
152
  this.logger.info(`${log}.client.closed`);
150
153
  p.reset();
151
154
  });
@@ -155,7 +158,7 @@ class SshClient {
155
158
  await persistentClient.ensure(); // warm up a connection
156
159
  return new Promise((resolve, reject) => {
157
160
  const server = net.createServer({ pauseOnConnect: true }, async (localSocket) => {
158
- const sockLog = `${log}.sock_${randomBytes(1).toString('hex')}`;
161
+ const sockLog = `${log}.sock_${randomBytes(1).toString("hex")}`;
159
162
  // this.logger.info(`${sockLog}.localSocket: start connection`);
160
163
  let conn;
161
164
  try {
@@ -175,7 +178,7 @@ class SshClient {
175
178
  localSocket.setNoDelay(true);
176
179
  let stream;
177
180
  try {
178
- stream = await forwardOut(this.logger, conn, '127.0.0.1', 0, '127.0.0.1', ports.remotePort);
181
+ stream = await forwardOut(this.logger, conn, "127.0.0.1", 0, "127.0.0.1", ports.remotePort);
179
182
  }
180
183
  catch (e) {
181
184
  this.logger.error(`${sockLog}.forwardOut.err: ${e}`);
@@ -186,42 +189,42 @@ class SshClient {
186
189
  stream.pipe(localSocket);
187
190
  localSocket.resume();
188
191
  // this.logger.info(`${sockLog}.forwardOut: connected`);
189
- stream.on('error', (err) => {
192
+ stream.on("error", (err) => {
190
193
  this.logger.error(`${sockLog}.stream.error: ${err}`);
191
194
  localSocket.end();
192
195
  stream.end();
193
196
  });
194
- stream.on('close', () => {
197
+ stream.on("close", () => {
195
198
  // this.logger.info(`${sockLog}.stream.close: closed`);
196
199
  localSocket.end();
197
200
  stream.end();
198
201
  });
199
- localSocket.on('close', () => {
202
+ localSocket.on("close", () => {
200
203
  this.logger.info(`${sockLog}.localSocket: closed`);
201
204
  localSocket.end();
202
205
  stream.end();
203
206
  });
204
207
  });
205
- server.listen(ports.localPort, '127.0.0.1', () => {
208
+ server.listen(ports.localPort, "127.0.0.1", () => {
206
209
  this.logger.info(`${log}.server: started listening`);
207
210
  this.forwardedServers.push(server);
208
211
  resolve({ server });
209
212
  });
210
- server.on('error', (err) => {
213
+ server.on("error", (err) => {
211
214
  server.close();
212
215
  reject(new Error(`${log}.server: error: ${JSON.stringify(err)}`));
213
216
  });
214
- server.on('close', () => {
217
+ server.on("close", () => {
215
218
  this.logger.info(`${log}.server: closed ${JSON.stringify(ports)}`);
216
219
  this.forwardedServers = this.forwardedServers.filter((s) => s !== server);
217
220
  });
218
221
  });
219
222
  }
220
223
  closeForwardedPorts() {
221
- this.logger.info('[SSH] Closing all forwarded ports...');
224
+ this.logger.info("[SSH] Closing all forwarded ports...");
222
225
  this.forwardedServers.forEach((server) => {
223
226
  const rawAddress = server.address();
224
- if (rawAddress && typeof rawAddress !== 'string') {
227
+ if (rawAddress && typeof rawAddress !== "string") {
225
228
  const address = rawAddress;
226
229
  this.logger.info(`[SSH] Closing port forward for server ${address.address}:${address.port}`);
227
230
  }
@@ -230,10 +233,10 @@ class SshClient {
230
233
  this.forwardedServers = [];
231
234
  }
232
235
  /**
233
- * Checks if a specified host is available by performing a DNS lookup.
234
- * @param hostname - The hostname or IP address to check.
235
- * @returns A promise resolving with `true` if the host is reachable, otherwise `false`.
236
- */
236
+ * Checks if a specified host is available by performing a DNS lookup.
237
+ * @param hostname - The hostname or IP address to check.
238
+ * @returns A promise resolving with `true` if the host is reachable, otherwise `false`.
239
+ */
237
240
  static async checkHostAvailability(hostname) {
238
241
  return new Promise((resolve) => {
239
242
  dns.lookup(hostname, (err) => {
@@ -256,7 +259,7 @@ class SshClient {
256
259
  return resolve(false);
257
260
  }
258
261
  catch (err) {
259
- console.log('Error parsing privateKey');
262
+ console.log("Error parsing privateKey");
260
263
  reject(new Error(`ssh.isPassphraseRequiredForKey: err ${err}`));
261
264
  }
262
265
  });
@@ -332,12 +335,12 @@ class SshClient {
332
335
  }
333
336
  rmdir(sftp, path) {
334
337
  return new Promise((resolve, reject) => {
335
- sftp.rmdir(path, (err) => err ? reject(err) : resolve(true));
338
+ sftp.rmdir(path, (err) => (err ? reject(err) : resolve(true)));
336
339
  });
337
340
  }
338
341
  unlink(sftp, path) {
339
342
  return new Promise((resolve, reject) => {
340
- sftp.unlink(path, (err) => err ? reject(err) : resolve(true));
343
+ sftp.unlink(path, (err) => (err ? reject(err) : resolve(true)));
341
344
  });
342
345
  }
343
346
  async deleteFolder(path) {
@@ -361,7 +364,7 @@ class SshClient {
361
364
  }
362
365
  catch (e) {
363
366
  this.logger.error(e);
364
- const message = e instanceof Error ? e.message : '';
367
+ const message = e instanceof Error ? e.message : "";
365
368
  throw new Error(`ssh.deleteFolder: path: ${path}, message: ${message}`);
366
369
  }
367
370
  });
@@ -504,8 +507,8 @@ class SshClient {
504
507
  */
505
508
  __createRemoteDirectory(sftp, remotePath) {
506
509
  return new Promise((resolve, reject) => {
507
- const directories = remotePath.split('/');
508
- let currentPath = '';
510
+ const directories = remotePath.split("/");
511
+ let currentPath = "";
509
512
  const createNext = (index) => {
510
513
  if (index >= directories.length) {
511
514
  return resolve();
@@ -536,8 +539,8 @@ class SshClient {
536
539
  */
537
540
  ensureRemoteDirCreated(remotePath, mode = 0o755) {
538
541
  return this.withSftp(async (sftp) => {
539
- const directories = remotePath.split('/');
540
- let currentPath = '';
542
+ const directories = remotePath.split("/");
543
+ let currentPath = "";
541
544
  for (const directory of directories) {
542
545
  currentPath += `${directory}/`;
543
546
  try {
@@ -589,13 +592,13 @@ class SshClient {
589
592
  }
590
593
  async function connect(client, config, onError, onClose) {
591
594
  return new Promise((resolve, reject) => {
592
- client.on('ready', () => {
595
+ client.on("ready", () => {
593
596
  resolve(client);
594
597
  });
595
- client.on('error', (err) => {
598
+ client.on("error", (err) => {
596
599
  reject(new Error(`ssh.connect: ${err}`));
597
600
  });
598
- client.on('close', () => {
601
+ client.on("close", () => {
599
602
  });
600
603
  client.connect(config);
601
604
  // Remove TCP buffering.
@@ -1 +1 @@
1
- {"version":3,"file":"ssh.js","sources":["../../src/ssh/ssh.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-misused-promises */\n/* eslint-disable @typescript-eslint/no-base-to-string */\nimport type { ConnectConfig, ClientChannel, SFTPWrapper } from 'ssh2';\nimport ssh, { Client } from 'ssh2';\nimport net from 'node:net';\nimport dns from 'node:dns';\nimport fs from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport upath from 'upath';\nimport { RetryablePromise, retry, type MiLogger, Retry3TimesWithDelay } from '@milaboratories/ts-helpers';\nimport { randomBytes } from 'node:crypto';\nimport { SFTPUploadError, SFTPError } from './ssh_errors';\n\nconst defaultConfig: ConnectConfig = {\n keepaliveInterval: 60000,\n keepaliveCountMax: 10,\n};\n\nexport type SshAuthMethods = 'publickey' | 'password';\nexport type SshAuthMethodsResult = SshAuthMethods[];\nexport type SshDirContent = {\n files: string[];\n directories: string[];\n};\n\nexport class SshClient {\n private config?: ConnectConfig;\n public homeDir?: string;\n private forwardedServers: net.Server[] = [];\n\n constructor(\n private readonly logger: MiLogger,\n private readonly client: Client,\n ) {}\n\n /**\n * Initializes the SshClient and establishes a connection using the provided configuration.\n * @param config - The connection configuration object for the SSH client.\n * @returns A new instance of SshClient with an active connection.\n */\n public static async init(logger: MiLogger, config: ConnectConfig): Promise<SshClient> {\n const withDefaults = {\n ...defaultConfig,\n ...config,\n };\n\n const client = new SshClient(logger, new Client());\n await client.connect(withDefaults);\n\n return client;\n }\n\n public getForwardedServers() {\n return this.forwardedServers;\n }\n\n public getFullHostName() {\n return `${this.config?.host}:${this.config?.port}`;\n }\n\n public getUserName() {\n return this.config?.username;\n }\n\n /**\n * Connects to the SSH server using the specified configuration.\n * @param config - The connection configuration object for the SSH client.\n * @returns A promise that resolves when the connection is established or rejects on error.\n */\n public async connect(config: ConnectConfig) {\n this.config = config;\n return await connect(this.client, config, () => {}, () => {});\n }\n\n /**\n * Executes a command on the SSH server.\n * @param command - The command to execute on the remote server.\n * @returns A promise resolving with the command's stdout and stderr outputs.\n */\n public async exec(command: string): Promise<SshExecResult> {\n return new Promise((resolve, reject) => {\n this.client.exec(command, (err: any, stream: ClientChannel) => {\n if (err) {\n return reject(new Error(`ssh.exec: ${command}: ${err}`));\n }\n\n let stdout = '';\n let stderr = '';\n\n stream.on('close', (code: number) => {\n if (code === 0) {\n resolve({ stdout, stderr });\n } else {\n reject(new Error(`Command ${command} exited with code ${code}, stdout: ${stdout}, stderr: ${stderr}`));\n }\n }).on('data', (data: ArrayBuffer) => {\n stdout += data.toString();\n }).stderr.on('data', (data: ArrayBuffer) => {\n stderr += data.toString();\n });\n });\n });\n }\n\n /**\n * Retrieves the supported authentication methods for a given host and port.\n * @param host - The hostname or IP address of the server.\n * @param port - The port number to connect to on the server.\n * @returns 'publickey' | 'password'[] A promise resolving with a list of supported authentication methods.\n */\n public static async getAuthTypes(host: string, port: number): Promise<SshAuthMethodsResult> {\n return new Promise((resolve) => {\n let stdout = '';\n const conn = new Client();\n\n conn.on('ready', () => {\n conn.end();\n const types = this.extractAuthMethods(stdout);\n resolve(types.length === 0 ? ['publickey', 'password'] : types as SshAuthMethodsResult);\n });\n\n conn.on('error', () => {\n conn.end();\n resolve(['publickey', 'password']);\n });\n\n conn.connect({\n host,\n port,\n username: new Date().getTime().toString(),\n debug: (err) => {\n stdout += `${err}\\n`;\n },\n });\n });\n }\n\n /**\n * Extracts authentication methods from debug logs.\n * @param log - The debug log output containing authentication information.\n * @returns An array of extracted authentication methods.\n */\n private static extractAuthMethods(log: string): string[] {\n const match = log.match(/Inbound: Received USERAUTH_FAILURE \\((.+)\\)/);\n return match && match[1] ? match[1].split(',').map((method) => method.trim()) : [];\n }\n\n /**\n * Sets up port forwarding between a remote port on the SSH server and a local port.\n * A new connection is used for this operation instead of an existing one.\n * @param ports - An object specifying the remote and local port configuration.\n * @param config - Optional connection configuration for the SSH client.\n * @returns { server: net.Server } A promise resolving with the created server instance.\n */\n public async forwardPort(ports: { remotePort: number; localPort: number; localHost?: string }, config?: ConnectConfig): Promise<{ server: net.Server }> {\n const log = `ssh.forward:${ports.localPort}:${ports.remotePort}.id_${randomBytes(1).toString('hex')}`;\n config = config ?? this.config;\n\n // we make this thing persistent so that if the connection\n // drops (it happened in the past because of lots of errors and forwardOut opened channels),\n // we'll recreate it here.\n const persistentClient = new RetryablePromise((p: RetryablePromise<Client>) => {\n return new Promise<Client>((resolve, reject) => {\n const client = new Client();\n\n client.on('ready', () => {\n this.logger.info(`${log}.client.ready`);\n resolve(client);\n });\n\n client.on('error', (err) => {\n this.logger.info(`${log}.client.error: ${err}`);\n p.reset();\n reject(err);\n });\n\n client.on('close', () => {\n this.logger.info(`${log}.client.closed`);\n p.reset();\n });\n\n client.connect(config!);\n });\n });\n\n await persistentClient.ensure(); // warm up a connection\n\n return new Promise((resolve, reject) => {\n const server = net.createServer({ pauseOnConnect: true }, async (localSocket) => {\n const sockLog = `${log}.sock_${randomBytes(1).toString('hex')}`;\n // this.logger.info(`${sockLog}.localSocket: start connection`);\n let conn: Client;\n try {\n conn = await persistentClient.ensure();\n } catch (e: unknown) {\n this.logger.info(`${sockLog}.persistentClient.catch: ${e}`);\n localSocket.end();\n return;\n }\n\n // Remove TCP buffering.\n // Although it means less throughput (bad), it also less latency (good).\n // It could help when we have\n // small messages like in our grpc transactions.\n // And it also could help when we have tcp forwarding to not buffer messages in the middle.\n (conn as any).setNoDelay(true);\n localSocket.setNoDelay(true);\n\n let stream: ClientChannel;\n try {\n stream = await forwardOut(this.logger, conn, '127.0.0.1', 0, '127.0.0.1', ports.remotePort);\n } catch (e: unknown) {\n this.logger.error(`${sockLog}.forwardOut.err: ${e}`);\n localSocket.end();\n return;\n }\n\n localSocket.pipe(stream);\n stream.pipe(localSocket);\n localSocket.resume();\n // this.logger.info(`${sockLog}.forwardOut: connected`);\n\n stream.on('error', (err: unknown) => {\n this.logger.error(`${sockLog}.stream.error: ${err}`);\n localSocket.end();\n stream.end();\n });\n stream.on('close', () => {\n // this.logger.info(`${sockLog}.stream.close: closed`);\n localSocket.end();\n stream.end();\n });\n localSocket.on('close', () => {\n this.logger.info(`${sockLog}.localSocket: closed`);\n localSocket.end();\n stream.end();\n });\n });\n\n server.listen(ports.localPort, '127.0.0.1', () => {\n this.logger.info(`${log}.server: started listening`);\n this.forwardedServers.push(server);\n resolve({ server });\n });\n\n server.on('error', (err) => {\n server.close();\n reject(new Error(`${log}.server: error: ${JSON.stringify(err)}`));\n });\n\n server.on('close', () => {\n this.logger.info(`${log}.server: closed ${JSON.stringify(ports)}`);\n this.forwardedServers = this.forwardedServers.filter((s) => s !== server);\n });\n });\n }\n\n public closeForwardedPorts(): void {\n this.logger.info('[SSH] Closing all forwarded ports...');\n this.forwardedServers.forEach((server) => {\n const rawAddress = server.address();\n if (rawAddress && typeof rawAddress !== 'string') {\n const address: net.AddressInfo = rawAddress;\n this.logger.info(`[SSH] Closing port forward for server ${address.address}:${address.port}`);\n }\n\n server.close();\n });\n this.forwardedServers = [];\n }\n\n /**\n * Checks if a specified host is available by performing a DNS lookup.\n * @param hostname - The hostname or IP address to check.\n * @returns A promise resolving with `true` if the host is reachable, otherwise `false`.\n */\n public static async checkHostAvailability(hostname: string): Promise<boolean> {\n return new Promise((resolve) => {\n dns.lookup(hostname, (err) => {\n resolve(!err);\n });\n });\n }\n\n /**\n * Determines whether a private key requires a passphrase for use.\n * @param privateKey - The private key content to check.\n * @returns A promise resolving with `true` if a passphrase is required, otherwise `false`.\n */\n public static async isPassphraseRequiredForKey(privateKey: string): Promise<boolean> {\n return new Promise((resolve, reject) => {\n try {\n const keyOrError = ssh.utils.parseKey(privateKey);\n if (keyOrError instanceof Error) {\n resolve(true);\n }\n return resolve(false);\n } catch (err: unknown) {\n console.log('Error parsing privateKey');\n reject(new Error(`ssh.isPassphraseRequiredForKey: err ${err}`));\n }\n });\n }\n\n /**\n * Uploads a local file to a remote server via SFTP.\n * This function creates new SFTP connection\n * @param localPath - The local file path.\n * @param remotePath - The remote file path on the server.\n * @returns A promise resolving with `true` if the file was successfully uploaded.\n */\n public async uploadFile(localPath: string, remotePath: string): Promise<boolean> {\n return await retry<boolean>(\n async () => {\n return await this.withSftp(async (sftp) => {\n return new Promise((resolve, reject) => {\n sftp.fastPut(localPath, remotePath, (err) => {\n if (err) {\n const newErr = new SFTPUploadError(err, localPath, remotePath);\n return reject(newErr);\n }\n resolve(true);\n });\n });\n });\n },\n Retry3TimesWithDelay,\n (e: any) => SFTPError.from(e)?.isGenericFailure ?? false, // retry unknown upload errors\n );\n }\n\n public async withSftp<R>(callback: (sftp: SFTPWrapper) => Promise<R>): Promise<R> {\n return new Promise((resolve, reject) => {\n this.client.sftp((err, sftp) => {\n if (err) {\n return reject(new Error(`ssh.withSftp: sftp err: ${err}`, { cause: err }));\n }\n\n callback(sftp)\n .then(resolve)\n .catch((err) => {\n reject(new Error(`ssh.withSftp.callback: err ${err}`, { cause: err }));\n })\n .finally(() => {\n sftp?.end();\n });\n });\n });\n }\n\n public async writeFileOnTheServer(remotePath: string, data: string | Buffer, mode: number = 0o660) {\n return this.withSftp(async (sftp) => {\n return this.writeFile(sftp, remotePath, data, mode);\n });\n }\n\n public async getForderStructure(sftp: SFTPWrapper, remotePath: string, data: SshDirContent = { files: [], directories: [] }): Promise<SshDirContent> {\n return new Promise((resolve, reject) => {\n sftp.readdir(remotePath, async (err, items) => {\n if (err) {\n return reject(err);\n }\n\n for (const item of items) {\n const itemPath = `${remotePath}/${item.filename}`;\n if (item.attrs.isDirectory()) {\n data.directories.push(itemPath);\n try {\n await this.getForderStructure(sftp, itemPath, data);\n } catch (error) {\n return reject(error instanceof Error ? error : new Error(String(error)));\n }\n } else {\n data.files.push(itemPath);\n }\n }\n resolve(data);\n });\n });\n }\n\n public rmdir(sftp: SFTPWrapper, path: string) {\n return new Promise((resolve, reject) => {\n sftp.rmdir(path, (err) => err ? reject(err) : resolve(true));\n });\n }\n\n public unlink(sftp: SFTPWrapper, path: string) {\n return new Promise((resolve, reject) => {\n sftp.unlink(path, (err) => err ? reject(err) : resolve(true));\n });\n }\n\n public async deleteFolder(path: string) {\n return this.withSftp(async (sftp) => {\n try {\n const list = await this.getForderStructure(sftp, path);\n this.logger.info(`ssh.deleteFolder list of files and directories`);\n this.logger.info(`ssh.deleteFolder list of files: ${list.files}`);\n this.logger.info(`ssh.deleteFolder list of directories: ${list.directories}`);\n\n for (const filePath of list.files) {\n this.logger.info(`ssh.deleteFolder unlink file ${filePath}`);\n await this.unlink(sftp, filePath);\n }\n\n list.directories.sort((a, b) => b.length - a.length);\n\n for (const directoryPath of list.directories) {\n this.logger.info(`ssh.deleteFolder rmdir ${directoryPath}`);\n await this.rmdir(sftp, directoryPath);\n }\n\n await this.rmdir(sftp, path);\n return true;\n } catch (e: unknown) {\n this.logger.error(e);\n const message = e instanceof Error ? e.message : '';\n throw new Error(`ssh.deleteFolder: path: ${path}, message: ${message}`);\n }\n });\n }\n\n public async readFile(remotePath: string): Promise<string> {\n return this.withSftp(async (sftp) => {\n return new Promise((resolve, reject) => {\n sftp.readFile(remotePath, (err, buffer) => {\n if (err) {\n return reject(new Error(`ssh.readFile: ${err}`));\n }\n resolve(buffer.toString());\n });\n });\n });\n }\n\n async chmod(path: string, mode: number) {\n return this.withSftp(async (sftp) => {\n return new Promise((resolve, reject) => {\n sftp.chmod(path, mode, (err) => {\n if (err) {\n return reject(new Error(`ssh.chmod: ${err}, path: ${path}, mode: ${mode}`));\n }\n return resolve(undefined);\n });\n });\n });\n }\n\n async checkFileExists(remotePath: string) {\n return this.withSftp(async (sftp) => {\n return new Promise((resolve, reject) => {\n sftp.stat(remotePath, (err: Error | undefined, stats) => {\n if (err) {\n if ((err as unknown as { code?: number })?.code === 2) {\n return resolve(false);\n }\n return reject(new Error(`ssh.checkFileExists: err ${err}`));\n }\n resolve(stats.isFile());\n });\n });\n });\n }\n\n async checkPathExists(remotePath: string): Promise<{ exists: boolean; isFile: boolean; isDirectory: boolean }> {\n return this.withSftp(async (sftp) => {\n return new Promise((resolve, reject) => {\n sftp.stat(remotePath, (err, stats) => {\n if (err) {\n if ((err as Error & { code: number }).code === 2) {\n return resolve({ exists: false, isFile: false, isDirectory: false });\n }\n return reject(new Error(`ssh.checkPathExists: ${err}`));\n }\n resolve({\n exists: true,\n isFile: stats.isFile(),\n isDirectory: stats.isDirectory(),\n });\n });\n });\n });\n }\n\n private async writeFile(sftp: SFTPWrapper, remotePath: string, data: string | Buffer, mode: number = 0o660): Promise<boolean> {\n return new Promise((resolve, reject) => {\n sftp.writeFile(remotePath, data, { mode }, (err) => {\n if (err) {\n return reject(new Error(`ssh.writeFile: err ${err}, remotePath: ${remotePath}`));\n }\n resolve(true);\n });\n });\n }\n\n public uploadFileUsingExistingSftp(sftp: SFTPWrapper, localPath: string, remotePath: string, mode: number = 0o660) {\n return new Promise((resolve, reject) => {\n void readFile(localPath).then(async (result: Buffer) => {\n return this.writeFile(sftp, remotePath, result, mode)\n .then(() => {\n resolve(undefined);\n })\n .catch((err) => {\n const msg = `uploadFileUsingExistingSftp: ${err}`;\n this.logger.error(msg);\n reject(new Error(msg));\n });\n });\n });\n }\n\n private async __uploadDirectory(sftp: SFTPWrapper, localDir: string, remoteDir: string, mode: number = 0o660): Promise<void> {\n return new Promise((resolve, reject) => {\n fs.readdir(localDir, async (err, files) => {\n if (err) {\n return reject(new Error(`ssh.__uploadDir: err ${err}, localDir: ${localDir}, remoteDir: ${remoteDir}`));\n }\n\n try {\n await this.__createRemoteDirectory(sftp, remoteDir);\n for (const file of files) {\n const localPath = upath.join(localDir, file);\n const remotePath = `${remoteDir}/${file}`;\n\n if (fs.lstatSync(localPath).isDirectory()) {\n await this.__uploadDirectory(sftp, localPath, remotePath, mode);\n } else {\n await this.uploadFileUsingExistingSftp(sftp, localPath, remotePath, mode);\n }\n }\n\n resolve();\n } catch (err) {\n const msg = `ssh.__uploadDir: catched err ${err}`;\n this.logger.error(msg);\n reject(new Error(msg));\n }\n });\n });\n }\n\n /**\n * Uploads a local directory and its contents (including subdirectories) to the remote server via SFTP.\n * @param localDir - The path to the local directory to upload.\n * @param remoteDir - The path to the remote directory on the server.\n * @returns A promise that resolves when the directory and its contents are uploaded.\n */\n public async uploadDirectory(localDir: string, remoteDir: string, mode: number = 0o660): Promise<void> {\n return new Promise((resolve, reject) => {\n void this.withSftp(async (sftp: SFTPWrapper) => {\n try {\n await this.__uploadDirectory(sftp, localDir, remoteDir, mode);\n resolve();\n } catch (e: unknown) {\n reject(new Error(`ssh.uploadDirectory: ${e}`));\n }\n });\n });\n }\n\n /**\n * Ensures that a remote directory and all its parent directories exist.\n * @param sftp - The SFTP wrapper.\n * @param remotePath - The path to the remote directory.\n * @returns A promise that resolves when the directory is created.\n */\n private __createRemoteDirectory(sftp: SFTPWrapper, remotePath: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const directories = remotePath.split('/');\n let currentPath = '';\n\n const createNext = (index: number) => {\n if (index >= directories.length) {\n return resolve();\n }\n\n currentPath += `${directories[index]}/`;\n\n sftp.stat(currentPath, (err) => {\n if (err) {\n sftp.mkdir(currentPath, (err) => {\n if (err) {\n return reject(new Error(`ssh.__createRemDir: err ${err}, remotePath: ${remotePath}`));\n }\n createNext(index + 1);\n });\n } else {\n createNext(index + 1);\n }\n });\n };\n\n createNext(0);\n });\n }\n\n /**\n * Ensures that a remote directory and all its parent directories exist.\n * @param sftp - The SFTP wrapper.\n * @param remotePath - The path to the remote directory.\n * @returns A promise that resolves when the directory is created.\n */\n public ensureRemoteDirCreated(remotePath: string, mode: number = 0o755): Promise<void> {\n return this.withSftp(async (sftp) => {\n const directories = remotePath.split('/');\n let currentPath = '';\n\n for (const directory of directories) {\n currentPath += `${directory}/`;\n\n try {\n await new Promise<void>((resolve, reject) => {\n sftp.stat(currentPath, (err) => {\n if (!err) return resolve();\n\n sftp.mkdir(currentPath, { mode }, (err) => {\n if (err) {\n return reject(new Error(`ssh.createRemoteDir: err ${err}, remotePath: ${remotePath}`));\n }\n resolve();\n });\n });\n });\n } catch (error) {\n console.error(`Failed to create directory: ${currentPath}`, error);\n throw error;\n }\n }\n });\n }\n\n /**\n * Downloads a file from the remote server to a local path via SFTP.\n * @param remotePath - The remote file path on the server.\n * @param localPath - The local file path to save the file.\n * @returns A promise resolving with `true` if the file was successfully downloaded.\n */\n public async downloadFile(remotePath: string, localPath: string): Promise<boolean> {\n return this.withSftp(async (sftp) => {\n return new Promise((resolve, reject) => {\n sftp.fastGet(remotePath, localPath, (err) => {\n if (err) {\n return reject(new Error(`ssh.downloadFile: err ${err}, remotePath: ${remotePath}, localPath: ${localPath}`));\n }\n resolve(true);\n });\n });\n });\n }\n\n /**\n * Closes the SSH client connection and forwarded ports.\n */\n public close(): void {\n this.closeForwardedPorts();\n this.client.end();\n }\n}\n\nexport type SshExecResult = { stdout: string; stderr: string };\n\nasync function connect(\n client: Client,\n config: ConnectConfig,\n onError: (e: unknown) => void,\n onClose: () => void,\n): Promise<Client> {\n return new Promise((resolve, reject) => {\n client.on('ready', () => {\n resolve(client);\n });\n\n client.on('error', (err: unknown) => {\n onError(err);\n reject(new Error(`ssh.connect: ${err}`));\n });\n\n client.on('close', () => {\n onClose();\n });\n\n client.connect(config);\n\n // Remove TCP buffering.\n // Although it means less throughput (bad), it also means less latency (good).\n // It could help when we have\n // small messages like in our grpc transactions.\n // And it also could help when we have tcp forwarding to not buffer messages in the middle.\n (client as any).setNoDelay(true);\n });\n}\n\nasync function forwardOut(logger: MiLogger, conn: Client, localHost: string, localPort: number, remoteHost: string, remotePort: number): Promise<ClientChannel> {\n return new Promise((resolve, reject) => {\n conn.forwardOut(localHost, localPort, remoteHost, remotePort, (err, stream) => {\n if (err) {\n logger.error(`forwardOut.error: ${err}`);\n return reject(err);\n }\n\n return resolve(stream);\n });\n });\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ssh.js","sources":["../../src/ssh/ssh.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-misused-promises */\n/* eslint-disable @typescript-eslint/no-base-to-string */\nimport type { ConnectConfig, ClientChannel, SFTPWrapper } from \"ssh2\";\nimport ssh, { Client } from \"ssh2\";\nimport net from \"node:net\";\nimport dns from \"node:dns\";\nimport fs from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport upath from \"upath\";\nimport {\n RetryablePromise,\n retry,\n type MiLogger,\n Retry3TimesWithDelay,\n} from \"@milaboratories/ts-helpers\";\nimport { randomBytes } from \"node:crypto\";\nimport { SFTPUploadError, SFTPError } from \"./ssh_errors\";\n\nconst defaultConfig: ConnectConfig = {\n keepaliveInterval: 60000,\n keepaliveCountMax: 10,\n};\n\nexport type SshAuthMethods = \"publickey\" | \"password\";\nexport type SshAuthMethodsResult = SshAuthMethods[];\nexport type SshDirContent = {\n files: string[];\n directories: string[];\n};\n\nexport class SshClient {\n private config?: ConnectConfig;\n public homeDir?: string;\n private forwardedServers: net.Server[] = [];\n\n constructor(\n private readonly logger: MiLogger,\n private readonly client: Client,\n ) {}\n\n /**\n * Initializes the SshClient and establishes a connection using the provided configuration.\n * @param config - The connection configuration object for the SSH client.\n * @returns A new instance of SshClient with an active connection.\n */\n public static async init(logger: MiLogger, config: ConnectConfig): Promise<SshClient> {\n const withDefaults = {\n ...defaultConfig,\n ...config,\n };\n\n const client = new SshClient(logger, new Client());\n await client.connect(withDefaults);\n\n return client;\n }\n\n public getForwardedServers() {\n return this.forwardedServers;\n }\n\n public getFullHostName() {\n return `${this.config?.host}:${this.config?.port}`;\n }\n\n public getUserName() {\n return this.config?.username;\n }\n\n /**\n * Connects to the SSH server using the specified configuration.\n * @param config - The connection configuration object for the SSH client.\n * @returns A promise that resolves when the connection is established or rejects on error.\n */\n public async connect(config: ConnectConfig) {\n this.config = config;\n return await connect(\n this.client,\n config,\n () => {},\n () => {},\n );\n }\n\n /**\n * Executes a command on the SSH server.\n * @param command - The command to execute on the remote server.\n * @returns A promise resolving with the command's stdout and stderr outputs.\n */\n public async exec(command: string): Promise<SshExecResult> {\n return new Promise((resolve, reject) => {\n this.client.exec(command, (err: any, stream: ClientChannel) => {\n if (err) {\n return reject(new Error(`ssh.exec: ${command}: ${err}`));\n }\n\n let stdout = \"\";\n let stderr = \"\";\n\n stream\n .on(\"close\", (code: number) => {\n if (code === 0) {\n resolve({ stdout, stderr });\n } else {\n reject(\n new Error(\n `Command ${command} exited with code ${code}, stdout: ${stdout}, stderr: ${stderr}`,\n ),\n );\n }\n })\n .on(\"data\", (data: ArrayBuffer) => {\n stdout += data.toString();\n })\n .stderr.on(\"data\", (data: ArrayBuffer) => {\n stderr += data.toString();\n });\n });\n });\n }\n\n /**\n * Retrieves the supported authentication methods for a given host and port.\n * @param host - The hostname or IP address of the server.\n * @param port - The port number to connect to on the server.\n * @returns 'publickey' | 'password'[] A promise resolving with a list of supported authentication methods.\n */\n public static async getAuthTypes(host: string, port: number): Promise<SshAuthMethodsResult> {\n return new Promise((resolve) => {\n let stdout = \"\";\n const conn = new Client();\n\n conn.on(\"ready\", () => {\n conn.end();\n const types = this.extractAuthMethods(stdout);\n resolve(types.length === 0 ? [\"publickey\", \"password\"] : (types as SshAuthMethodsResult));\n });\n\n conn.on(\"error\", () => {\n conn.end();\n resolve([\"publickey\", \"password\"]);\n });\n\n conn.connect({\n host,\n port,\n username: new Date().getTime().toString(),\n debug: (err) => {\n stdout += `${err}\\n`;\n },\n });\n });\n }\n\n /**\n * Extracts authentication methods from debug logs.\n * @param log - The debug log output containing authentication information.\n * @returns An array of extracted authentication methods.\n */\n private static extractAuthMethods(log: string): string[] {\n const match = log.match(/Inbound: Received USERAUTH_FAILURE \\((.+)\\)/);\n return match && match[1] ? match[1].split(\",\").map((method) => method.trim()) : [];\n }\n\n /**\n * Sets up port forwarding between a remote port on the SSH server and a local port.\n * A new connection is used for this operation instead of an existing one.\n * @param ports - An object specifying the remote and local port configuration.\n * @param config - Optional connection configuration for the SSH client.\n * @returns { server: net.Server } A promise resolving with the created server instance.\n */\n public async forwardPort(\n ports: { remotePort: number; localPort: number; localHost?: string },\n config?: ConnectConfig,\n ): Promise<{ server: net.Server }> {\n const log = `ssh.forward:${ports.localPort}:${ports.remotePort}.id_${randomBytes(1).toString(\"hex\")}`;\n config = config ?? this.config;\n\n // we make this thing persistent so that if the connection\n // drops (it happened in the past because of lots of errors and forwardOut opened channels),\n // we'll recreate it here.\n const persistentClient = new RetryablePromise((p: RetryablePromise<Client>) => {\n return new Promise<Client>((resolve, reject) => {\n const client = new Client();\n\n client.on(\"ready\", () => {\n this.logger.info(`${log}.client.ready`);\n resolve(client);\n });\n\n client.on(\"error\", (err) => {\n this.logger.info(`${log}.client.error: ${err}`);\n p.reset();\n reject(err);\n });\n\n client.on(\"close\", () => {\n this.logger.info(`${log}.client.closed`);\n p.reset();\n });\n\n client.connect(config!);\n });\n });\n\n await persistentClient.ensure(); // warm up a connection\n\n return new Promise((resolve, reject) => {\n const server = net.createServer({ pauseOnConnect: true }, async (localSocket) => {\n const sockLog = `${log}.sock_${randomBytes(1).toString(\"hex\")}`;\n // this.logger.info(`${sockLog}.localSocket: start connection`);\n let conn: Client;\n try {\n conn = await persistentClient.ensure();\n } catch (e: unknown) {\n this.logger.info(`${sockLog}.persistentClient.catch: ${e}`);\n localSocket.end();\n return;\n }\n\n // Remove TCP buffering.\n // Although it means less throughput (bad), it also less latency (good).\n // It could help when we have\n // small messages like in our grpc transactions.\n // And it also could help when we have tcp forwarding to not buffer messages in the middle.\n (conn as any).setNoDelay(true);\n localSocket.setNoDelay(true);\n\n let stream: ClientChannel;\n try {\n stream = await forwardOut(\n this.logger,\n conn,\n \"127.0.0.1\",\n 0,\n \"127.0.0.1\",\n ports.remotePort,\n );\n } catch (e: unknown) {\n this.logger.error(`${sockLog}.forwardOut.err: ${e}`);\n localSocket.end();\n return;\n }\n\n localSocket.pipe(stream);\n stream.pipe(localSocket);\n localSocket.resume();\n // this.logger.info(`${sockLog}.forwardOut: connected`);\n\n stream.on(\"error\", (err: unknown) => {\n this.logger.error(`${sockLog}.stream.error: ${err}`);\n localSocket.end();\n stream.end();\n });\n stream.on(\"close\", () => {\n // this.logger.info(`${sockLog}.stream.close: closed`);\n localSocket.end();\n stream.end();\n });\n localSocket.on(\"close\", () => {\n this.logger.info(`${sockLog}.localSocket: closed`);\n localSocket.end();\n stream.end();\n });\n });\n\n server.listen(ports.localPort, \"127.0.0.1\", () => {\n this.logger.info(`${log}.server: started listening`);\n this.forwardedServers.push(server);\n resolve({ server });\n });\n\n server.on(\"error\", (err) => {\n server.close();\n reject(new Error(`${log}.server: error: ${JSON.stringify(err)}`));\n });\n\n server.on(\"close\", () => {\n this.logger.info(`${log}.server: closed ${JSON.stringify(ports)}`);\n this.forwardedServers = this.forwardedServers.filter((s) => s !== server);\n });\n });\n }\n\n public closeForwardedPorts(): void {\n this.logger.info(\"[SSH] Closing all forwarded ports...\");\n this.forwardedServers.forEach((server) => {\n const rawAddress = server.address();\n if (rawAddress && typeof rawAddress !== \"string\") {\n const address: net.AddressInfo = rawAddress;\n this.logger.info(\n `[SSH] Closing port forward for server ${address.address}:${address.port}`,\n );\n }\n\n server.close();\n });\n this.forwardedServers = [];\n }\n\n /**\n * Checks if a specified host is available by performing a DNS lookup.\n * @param hostname - The hostname or IP address to check.\n * @returns A promise resolving with `true` if the host is reachable, otherwise `false`.\n */\n public static async checkHostAvailability(hostname: string): Promise<boolean> {\n return new Promise((resolve) => {\n dns.lookup(hostname, (err) => {\n resolve(!err);\n });\n });\n }\n\n /**\n * Determines whether a private key requires a passphrase for use.\n * @param privateKey - The private key content to check.\n * @returns A promise resolving with `true` if a passphrase is required, otherwise `false`.\n */\n public static async isPassphraseRequiredForKey(privateKey: string): Promise<boolean> {\n return new Promise((resolve, reject) => {\n try {\n const keyOrError = ssh.utils.parseKey(privateKey);\n if (keyOrError instanceof Error) {\n resolve(true);\n }\n return resolve(false);\n } catch (err: unknown) {\n console.log(\"Error parsing privateKey\");\n reject(new Error(`ssh.isPassphraseRequiredForKey: err ${err}`));\n }\n });\n }\n\n /**\n * Uploads a local file to a remote server via SFTP.\n * This function creates new SFTP connection\n * @param localPath - The local file path.\n * @param remotePath - The remote file path on the server.\n * @returns A promise resolving with `true` if the file was successfully uploaded.\n */\n public async uploadFile(localPath: string, remotePath: string): Promise<boolean> {\n return await retry<boolean>(\n async () => {\n return await this.withSftp(async (sftp) => {\n return new Promise((resolve, reject) => {\n sftp.fastPut(localPath, remotePath, (err) => {\n if (err) {\n const newErr = new SFTPUploadError(err, localPath, remotePath);\n return reject(newErr);\n }\n resolve(true);\n });\n });\n });\n },\n Retry3TimesWithDelay,\n (e: any) => SFTPError.from(e)?.isGenericFailure ?? false, // retry unknown upload errors\n );\n }\n\n public async withSftp<R>(callback: (sftp: SFTPWrapper) => Promise<R>): Promise<R> {\n return new Promise((resolve, reject) => {\n this.client.sftp((err, sftp) => {\n if (err) {\n return reject(new Error(`ssh.withSftp: sftp err: ${err}`, { cause: err }));\n }\n\n callback(sftp)\n .then(resolve)\n .catch((err) => {\n reject(new Error(`ssh.withSftp.callback: err ${err}`, { cause: err }));\n })\n .finally(() => {\n sftp?.end();\n });\n });\n });\n }\n\n public async writeFileOnTheServer(\n remotePath: string,\n data: string | Buffer,\n mode: number = 0o660,\n ) {\n return this.withSftp(async (sftp) => {\n return this.writeFile(sftp, remotePath, data, mode);\n });\n }\n\n public async getForderStructure(\n sftp: SFTPWrapper,\n remotePath: string,\n data: SshDirContent = { files: [], directories: [] },\n ): Promise<SshDirContent> {\n return new Promise((resolve, reject) => {\n sftp.readdir(remotePath, async (err, items) => {\n if (err) {\n return reject(err);\n }\n\n for (const item of items) {\n const itemPath = `${remotePath}/${item.filename}`;\n if (item.attrs.isDirectory()) {\n data.directories.push(itemPath);\n try {\n await this.getForderStructure(sftp, itemPath, data);\n } catch (error) {\n return reject(error instanceof Error ? error : new Error(String(error)));\n }\n } else {\n data.files.push(itemPath);\n }\n }\n resolve(data);\n });\n });\n }\n\n public rmdir(sftp: SFTPWrapper, path: string) {\n return new Promise((resolve, reject) => {\n sftp.rmdir(path, (err) => (err ? reject(err) : resolve(true)));\n });\n }\n\n public unlink(sftp: SFTPWrapper, path: string) {\n return new Promise((resolve, reject) => {\n sftp.unlink(path, (err) => (err ? reject(err) : resolve(true)));\n });\n }\n\n public async deleteFolder(path: string) {\n return this.withSftp(async (sftp) => {\n try {\n const list = await this.getForderStructure(sftp, path);\n this.logger.info(`ssh.deleteFolder list of files and directories`);\n this.logger.info(`ssh.deleteFolder list of files: ${list.files}`);\n this.logger.info(`ssh.deleteFolder list of directories: ${list.directories}`);\n\n for (const filePath of list.files) {\n this.logger.info(`ssh.deleteFolder unlink file ${filePath}`);\n await this.unlink(sftp, filePath);\n }\n\n list.directories.sort((a, b) => b.length - a.length);\n\n for (const directoryPath of list.directories) {\n this.logger.info(`ssh.deleteFolder rmdir ${directoryPath}`);\n await this.rmdir(sftp, directoryPath);\n }\n\n await this.rmdir(sftp, path);\n return true;\n } catch (e: unknown) {\n this.logger.error(e);\n const message = e instanceof Error ? e.message : \"\";\n throw new Error(`ssh.deleteFolder: path: ${path}, message: ${message}`);\n }\n });\n }\n\n public async readFile(remotePath: string): Promise<string> {\n return this.withSftp(async (sftp) => {\n return new Promise((resolve, reject) => {\n sftp.readFile(remotePath, (err, buffer) => {\n if (err) {\n return reject(new Error(`ssh.readFile: ${err}`));\n }\n resolve(buffer.toString());\n });\n });\n });\n }\n\n async chmod(path: string, mode: number) {\n return this.withSftp(async (sftp) => {\n return new Promise((resolve, reject) => {\n sftp.chmod(path, mode, (err) => {\n if (err) {\n return reject(new Error(`ssh.chmod: ${err}, path: ${path}, mode: ${mode}`));\n }\n return resolve(undefined);\n });\n });\n });\n }\n\n async checkFileExists(remotePath: string) {\n return this.withSftp(async (sftp) => {\n return new Promise((resolve, reject) => {\n sftp.stat(remotePath, (err: Error | undefined, stats) => {\n if (err) {\n if ((err as unknown as { code?: number })?.code === 2) {\n return resolve(false);\n }\n return reject(new Error(`ssh.checkFileExists: err ${err}`));\n }\n resolve(stats.isFile());\n });\n });\n });\n }\n\n async checkPathExists(\n remotePath: string,\n ): Promise<{ exists: boolean; isFile: boolean; isDirectory: boolean }> {\n return this.withSftp(async (sftp) => {\n return new Promise((resolve, reject) => {\n sftp.stat(remotePath, (err, stats) => {\n if (err) {\n if ((err as Error & { code: number }).code === 2) {\n return resolve({ exists: false, isFile: false, isDirectory: false });\n }\n return reject(new Error(`ssh.checkPathExists: ${err}`));\n }\n resolve({\n exists: true,\n isFile: stats.isFile(),\n isDirectory: stats.isDirectory(),\n });\n });\n });\n });\n }\n\n private async writeFile(\n sftp: SFTPWrapper,\n remotePath: string,\n data: string | Buffer,\n mode: number = 0o660,\n ): Promise<boolean> {\n return new Promise((resolve, reject) => {\n sftp.writeFile(remotePath, data, { mode }, (err) => {\n if (err) {\n return reject(new Error(`ssh.writeFile: err ${err}, remotePath: ${remotePath}`));\n }\n resolve(true);\n });\n });\n }\n\n public uploadFileUsingExistingSftp(\n sftp: SFTPWrapper,\n localPath: string,\n remotePath: string,\n mode: number = 0o660,\n ) {\n return new Promise((resolve, reject) => {\n void readFile(localPath).then(async (result: Buffer) => {\n return this.writeFile(sftp, remotePath, result, mode)\n .then(() => {\n resolve(undefined);\n })\n .catch((err) => {\n const msg = `uploadFileUsingExistingSftp: ${err}`;\n this.logger.error(msg);\n reject(new Error(msg));\n });\n });\n });\n }\n\n private async __uploadDirectory(\n sftp: SFTPWrapper,\n localDir: string,\n remoteDir: string,\n mode: number = 0o660,\n ): Promise<void> {\n return new Promise((resolve, reject) => {\n fs.readdir(localDir, async (err, files) => {\n if (err) {\n return reject(\n new Error(\n `ssh.__uploadDir: err ${err}, localDir: ${localDir}, remoteDir: ${remoteDir}`,\n ),\n );\n }\n\n try {\n await this.__createRemoteDirectory(sftp, remoteDir);\n for (const file of files) {\n const localPath = upath.join(localDir, file);\n const remotePath = `${remoteDir}/${file}`;\n\n if (fs.lstatSync(localPath).isDirectory()) {\n await this.__uploadDirectory(sftp, localPath, remotePath, mode);\n } else {\n await this.uploadFileUsingExistingSftp(sftp, localPath, remotePath, mode);\n }\n }\n\n resolve();\n } catch (err) {\n const msg = `ssh.__uploadDir: catched err ${err}`;\n this.logger.error(msg);\n reject(new Error(msg));\n }\n });\n });\n }\n\n /**\n * Uploads a local directory and its contents (including subdirectories) to the remote server via SFTP.\n * @param localDir - The path to the local directory to upload.\n * @param remoteDir - The path to the remote directory on the server.\n * @returns A promise that resolves when the directory and its contents are uploaded.\n */\n public async uploadDirectory(\n localDir: string,\n remoteDir: string,\n mode: number = 0o660,\n ): Promise<void> {\n return new Promise((resolve, reject) => {\n void this.withSftp(async (sftp: SFTPWrapper) => {\n try {\n await this.__uploadDirectory(sftp, localDir, remoteDir, mode);\n resolve();\n } catch (e: unknown) {\n reject(new Error(`ssh.uploadDirectory: ${e}`));\n }\n });\n });\n }\n\n /**\n * Ensures that a remote directory and all its parent directories exist.\n * @param sftp - The SFTP wrapper.\n * @param remotePath - The path to the remote directory.\n * @returns A promise that resolves when the directory is created.\n */\n private __createRemoteDirectory(sftp: SFTPWrapper, remotePath: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const directories = remotePath.split(\"/\");\n let currentPath = \"\";\n\n const createNext = (index: number) => {\n if (index >= directories.length) {\n return resolve();\n }\n\n currentPath += `${directories[index]}/`;\n\n sftp.stat(currentPath, (err) => {\n if (err) {\n sftp.mkdir(currentPath, (err) => {\n if (err) {\n return reject(\n new Error(`ssh.__createRemDir: err ${err}, remotePath: ${remotePath}`),\n );\n }\n createNext(index + 1);\n });\n } else {\n createNext(index + 1);\n }\n });\n };\n\n createNext(0);\n });\n }\n\n /**\n * Ensures that a remote directory and all its parent directories exist.\n * @param sftp - The SFTP wrapper.\n * @param remotePath - The path to the remote directory.\n * @returns A promise that resolves when the directory is created.\n */\n public ensureRemoteDirCreated(remotePath: string, mode: number = 0o755): Promise<void> {\n return this.withSftp(async (sftp) => {\n const directories = remotePath.split(\"/\");\n let currentPath = \"\";\n\n for (const directory of directories) {\n currentPath += `${directory}/`;\n\n try {\n await new Promise<void>((resolve, reject) => {\n sftp.stat(currentPath, (err) => {\n if (!err) return resolve();\n\n sftp.mkdir(currentPath, { mode }, (err) => {\n if (err) {\n return reject(\n new Error(`ssh.createRemoteDir: err ${err}, remotePath: ${remotePath}`),\n );\n }\n resolve();\n });\n });\n });\n } catch (error) {\n console.error(`Failed to create directory: ${currentPath}`, error);\n throw error;\n }\n }\n });\n }\n\n /**\n * Downloads a file from the remote server to a local path via SFTP.\n * @param remotePath - The remote file path on the server.\n * @param localPath - The local file path to save the file.\n * @returns A promise resolving with `true` if the file was successfully downloaded.\n */\n public async downloadFile(remotePath: string, localPath: string): Promise<boolean> {\n return this.withSftp(async (sftp) => {\n return new Promise((resolve, reject) => {\n sftp.fastGet(remotePath, localPath, (err) => {\n if (err) {\n return reject(\n new Error(\n `ssh.downloadFile: err ${err}, remotePath: ${remotePath}, localPath: ${localPath}`,\n ),\n );\n }\n resolve(true);\n });\n });\n });\n }\n\n /**\n * Closes the SSH client connection and forwarded ports.\n */\n public close(): void {\n this.closeForwardedPorts();\n this.client.end();\n }\n}\n\nexport type SshExecResult = { stdout: string; stderr: string };\n\nasync function connect(\n client: Client,\n config: ConnectConfig,\n onError: (e: unknown) => void,\n onClose: () => void,\n): Promise<Client> {\n return new Promise((resolve, reject) => {\n client.on(\"ready\", () => {\n resolve(client);\n });\n\n client.on(\"error\", (err: unknown) => {\n onError(err);\n reject(new Error(`ssh.connect: ${err}`));\n });\n\n client.on(\"close\", () => {\n onClose();\n });\n\n client.connect(config);\n\n // Remove TCP buffering.\n // Although it means less throughput (bad), it also means less latency (good).\n // It could help when we have\n // small messages like in our grpc transactions.\n // And it also could help when we have tcp forwarding to not buffer messages in the middle.\n (client as any).setNoDelay(true);\n });\n}\n\nasync function forwardOut(\n logger: MiLogger,\n conn: Client,\n localHost: string,\n localPort: number,\n remoteHost: string,\n remotePort: number,\n): Promise<ClientChannel> {\n return new Promise((resolve, reject) => {\n conn.forwardOut(localHost, localPort, remoteHost, remotePort, (err, stream) => {\n if (err) {\n logger.error(`forwardOut.error: ${err}`);\n return reject(err);\n }\n\n return resolve(stream);\n });\n });\n}\n"],"names":[],"mappings":";;;;;;;;;;AAkBA,MAAM,aAAa,GAAkB;AACnC,IAAA,iBAAiB,EAAE,KAAK;AACxB,IAAA,iBAAiB,EAAE,EAAE;CACtB;MASY,SAAS,CAAA;AAMD,IAAA,MAAA;AACA,IAAA,MAAA;AANX,IAAA,MAAM;AACP,IAAA,OAAO;IACN,gBAAgB,GAAiB,EAAE;IAE3C,WAAA,CACmB,MAAgB,EAChB,MAAc,EAAA;QADd,IAAA,CAAA,MAAM,GAAN,MAAM;QACN,IAAA,CAAA,MAAM,GAAN,MAAM;IACtB;AAEH;;;;AAIG;AACI,IAAA,aAAa,IAAI,CAAC,MAAgB,EAAE,MAAqB,EAAA;AAC9D,QAAA,MAAM,YAAY,GAAG;AACnB,YAAA,GAAG,aAAa;AAChB,YAAA,GAAG,MAAM;SACV;QAED,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;AAClD,QAAA,MAAM,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC;AAElC,QAAA,OAAO,MAAM;IACf;IAEO,mBAAmB,GAAA;QACxB,OAAO,IAAI,CAAC,gBAAgB;IAC9B;IAEO,eAAe,GAAA;AACpB,QAAA,OAAO,CAAA,EAAG,IAAI,CAAC,MAAM,EAAE,IAAI,CAAA,CAAA,EAAI,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE;IACpD;IAEO,WAAW,GAAA;AAChB,QAAA,OAAO,IAAI,CAAC,MAAM,EAAE,QAAQ;IAC9B;AAEA;;;;AAIG;IACI,MAAM,OAAO,CAAC,MAAqB,EAAA;AACxC,QAAA,IAAI,CAAC,MAAM,GAAG,MAAM;AACpB,QAAA,OAAO,MAAM,OAAO,CAClB,IAAI,CAAC,MAAM,EACX,MAEQ,CACT;IACH;AAEA;;;;AAIG;IACI,MAAM,IAAI,CAAC,OAAe,EAAA;QAC/B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;AACrC,YAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAQ,EAAE,MAAqB,KAAI;gBAC5D,IAAI,GAAG,EAAE;AACP,oBAAA,OAAO,MAAM,CAAC,IAAI,KAAK,CAAC,CAAA,UAAA,EAAa,OAAO,CAAA,EAAA,EAAK,GAAG,CAAA,CAAE,CAAC,CAAC;gBAC1D;gBAEA,IAAI,MAAM,GAAG,EAAE;gBACf,IAAI,MAAM,GAAG,EAAE;gBAEf;AACG,qBAAA,EAAE,CAAC,OAAO,EAAE,CAAC,IAAY,KAAI;AAC5B,oBAAA,IAAI,IAAI,KAAK,CAAC,EAAE;AACd,wBAAA,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;oBAC7B;yBAAO;AACL,wBAAA,MAAM,CACJ,IAAI,KAAK,CACP,WAAW,OAAO,CAAA,kBAAA,EAAqB,IAAI,CAAA,UAAA,EAAa,MAAM,CAAA,UAAA,EAAa,MAAM,CAAA,CAAE,CACpF,CACF;oBACH;AACF,gBAAA,CAAC;AACA,qBAAA,EAAE,CAAC,MAAM,EAAE,CAAC,IAAiB,KAAI;AAChC,oBAAA,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE;AAC3B,gBAAA,CAAC;qBACA,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAiB,KAAI;AACvC,oBAAA,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE;AAC3B,gBAAA,CAAC,CAAC;AACN,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;AAEA;;;;;AAKG;AACI,IAAA,aAAa,YAAY,CAAC,IAAY,EAAE,IAAY,EAAA;AACzD,QAAA,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAI;YAC7B,IAAI,MAAM,GAAG,EAAE;AACf,YAAA,MAAM,IAAI,GAAG,IAAI,MAAM,EAAE;AAEzB,YAAA,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAK;gBACpB,IAAI,CAAC,GAAG,EAAE;gBACV,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC;AAC7C,gBAAA,OAAO,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,UAAU,CAAC,GAAI,KAA8B,CAAC;AAC3F,YAAA,CAAC,CAAC;AAEF,YAAA,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,MAAK;gBACpB,IAAI,CAAC,GAAG,EAAE;AACV,gBAAA,OAAO,CAAC,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;AACpC,YAAA,CAAC,CAAC;YAEF,IAAI,CAAC,OAAO,CAAC;gBACX,IAAI;gBACJ,IAAI;gBACJ,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;AACzC,gBAAA,KAAK,EAAE,CAAC,GAAG,KAAI;AACb,oBAAA,MAAM,IAAI,CAAA,EAAG,GAAG,CAAA,EAAA,CAAI;gBACtB,CAAC;AACF,aAAA,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;AAEA;;;;AAIG;IACK,OAAO,kBAAkB,CAAC,GAAW,EAAA;QAC3C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,6CAA6C,CAAC;AACtE,QAAA,OAAO,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE;IACpF;AAEA;;;;;;AAMG;AACI,IAAA,MAAM,WAAW,CACtB,KAAoE,EACpE,MAAsB,EAAA;QAEtB,MAAM,GAAG,GAAG,CAAA,YAAA,EAAe,KAAK,CAAC,SAAS,CAAA,CAAA,EAAI,KAAK,CAAC,UAAU,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA,CAAE;AACrG,QAAA,MAAM,GAAG,MAAM,IAAI,IAAI,CAAC,MAAM;;;;QAK9B,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,CAAC,CAAC,CAA2B,KAAI;YAC5E,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,KAAI;AAC7C,gBAAA,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE;AAE3B,gBAAA,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAK;oBACtB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA,EAAG,GAAG,CAAA,aAAA,CAAe,CAAC;oBACvC,OAAO,CAAC,MAAM,CAAC;AACjB,gBAAA,CAAC,CAAC;gBAEF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,KAAI;oBACzB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA,EAAG,GAAG,CAAA,eAAA,EAAkB,GAAG,CAAA,CAAE,CAAC;oBAC/C,CAAC,CAAC,KAAK,EAAE;oBACT,MAAM,CAAC,GAAG,CAAC;AACb,gBAAA,CAAC,CAAC;AAEF,gBAAA,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAK;oBACtB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA,EAAG,GAAG,CAAA,cAAA,CAAgB,CAAC;oBACxC,CAAC,CAAC,KAAK,EAAE;AACX,gBAAA,CAAC,CAAC;AAEF,gBAAA,MAAM,CAAC,OAAO,CAAC,MAAO,CAAC;AACzB,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;AAEF,QAAA,MAAM,gBAAgB,CAAC,MAAM,EAAE,CAAC;QAEhC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;AACrC,YAAA,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,CAAC,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,OAAO,WAAW,KAAI;AAC9E,gBAAA,MAAM,OAAO,GAAG,CAAA,EAAG,GAAG,SAAS,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;;AAE/D,gBAAA,IAAI,IAAY;AAChB,gBAAA,IAAI;AACF,oBAAA,IAAI,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE;gBACxC;gBAAE,OAAO,CAAU,EAAE;oBACnB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA,EAAG,OAAO,CAAA,yBAAA,EAA4B,CAAC,CAAA,CAAE,CAAC;oBAC3D,WAAW,CAAC,GAAG,EAAE;oBACjB;gBACF;;;;;;AAOC,gBAAA,IAAY,CAAC,UAAU,CAAC,IAAI,CAAC;AAC9B,gBAAA,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC;AAE5B,gBAAA,IAAI,MAAqB;AACzB,gBAAA,IAAI;oBACF,MAAM,GAAG,MAAM,UAAU,CACvB,IAAI,CAAC,MAAM,EACX,IAAI,EACJ,WAAW,EACX,CAAC,EACD,WAAW,EACX,KAAK,CAAC,UAAU,CACjB;gBACH;gBAAE,OAAO,CAAU,EAAE;oBACnB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA,EAAG,OAAO,CAAA,iBAAA,EAAoB,CAAC,CAAA,CAAE,CAAC;oBACpD,WAAW,CAAC,GAAG,EAAE;oBACjB;gBACF;AAEA,gBAAA,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC;AACxB,gBAAA,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;gBACxB,WAAW,CAAC,MAAM,EAAE;;gBAGpB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAY,KAAI;oBAClC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA,EAAG,OAAO,CAAA,eAAA,EAAkB,GAAG,CAAA,CAAE,CAAC;oBACpD,WAAW,CAAC,GAAG,EAAE;oBACjB,MAAM,CAAC,GAAG,EAAE;AACd,gBAAA,CAAC,CAAC;AACF,gBAAA,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAK;;oBAEtB,WAAW,CAAC,GAAG,EAAE;oBACjB,MAAM,CAAC,GAAG,EAAE;AACd,gBAAA,CAAC,CAAC;AACF,gBAAA,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAK;oBAC3B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA,EAAG,OAAO,CAAA,oBAAA,CAAsB,CAAC;oBAClD,WAAW,CAAC,GAAG,EAAE;oBACjB,MAAM,CAAC,GAAG,EAAE;AACd,gBAAA,CAAC,CAAC;AACJ,YAAA,CAAC,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,WAAW,EAAE,MAAK;gBAC/C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA,EAAG,GAAG,CAAA,0BAAA,CAA4B,CAAC;AACpD,gBAAA,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC;AAClC,gBAAA,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;AACrB,YAAA,CAAC,CAAC;YAEF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,KAAI;gBACzB,MAAM,CAAC,KAAK,EAAE;AACd,gBAAA,MAAM,CAAC,IAAI,KAAK,CAAC,CAAA,EAAG,GAAG,CAAA,gBAAA,EAAmB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA,CAAE,CAAC,CAAC;AACnE,YAAA,CAAC,CAAC;AAEF,YAAA,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAK;AACtB,gBAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,GAAG,CAAA,gBAAA,EAAmB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA,CAAE,CAAC;AAClE,gBAAA,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,MAAM,CAAC;AAC3E,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;IAEO,mBAAmB,GAAA;AACxB,QAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,sCAAsC,CAAC;QACxD,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,MAAM,KAAI;AACvC,YAAA,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,EAAE;AACnC,YAAA,IAAI,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE;gBAChD,MAAM,OAAO,GAAoB,UAAU;AAC3C,gBAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,CAAA,sCAAA,EAAyC,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAA,CAAE,CAC3E;YACH;YAEA,MAAM,CAAC,KAAK,EAAE;AAChB,QAAA,CAAC,CAAC;AACF,QAAA,IAAI,CAAC,gBAAgB,GAAG,EAAE;IAC5B;AAEA;;;;AAIG;AACI,IAAA,aAAa,qBAAqB,CAAC,QAAgB,EAAA;AACxD,QAAA,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,KAAI;YAC7B,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,GAAG,KAAI;AAC3B,gBAAA,OAAO,CAAC,CAAC,GAAG,CAAC;AACf,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;AAEA;;;;AAIG;AACI,IAAA,aAAa,0BAA0B,CAAC,UAAkB,EAAA;QAC/D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;AACrC,YAAA,IAAI;gBACF,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC;AACjD,gBAAA,IAAI,UAAU,YAAY,KAAK,EAAE;oBAC/B,OAAO,CAAC,IAAI,CAAC;gBACf;AACA,gBAAA,OAAO,OAAO,CAAC,KAAK,CAAC;YACvB;YAAE,OAAO,GAAY,EAAE;AACrB,gBAAA,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC;gBACvC,MAAM,CAAC,IAAI,KAAK,CAAC,uCAAuC,GAAG,CAAA,CAAE,CAAC,CAAC;YACjE;AACF,QAAA,CAAC,CAAC;IACJ;AAEA;;;;;;AAMG;AACI,IAAA,MAAM,UAAU,CAAC,SAAiB,EAAE,UAAkB,EAAA;AAC3D,QAAA,OAAO,MAAM,KAAK,CAChB,YAAW;YACT,OAAO,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,KAAI;gBACxC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;oBACrC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,UAAU,EAAE,CAAC,GAAG,KAAI;wBAC1C,IAAI,GAAG,EAAE;4BACP,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,GAAG,EAAE,SAAS,EAAE,UAAU,CAAC;AAC9D,4BAAA,OAAO,MAAM,CAAC,MAAM,CAAC;wBACvB;wBACA,OAAO,CAAC,IAAI,CAAC;AACf,oBAAA,CAAC,CAAC;AACJ,gBAAA,CAAC,CAAC;AACJ,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,EACD,oBAAoB,EACpB,CAAC,CAAM,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,gBAAgB,IAAI,KAAK,CACzD;IACH;IAEO,MAAM,QAAQ,CAAI,QAA2C,EAAA;QAClE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;YACrC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,IAAI,KAAI;gBAC7B,IAAI,GAAG,EAAE;AACP,oBAAA,OAAO,MAAM,CAAC,IAAI,KAAK,CAAC,2BAA2B,GAAG,CAAA,CAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;gBAC5E;gBAEA,QAAQ,CAAC,IAAI;qBACV,IAAI,CAAC,OAAO;AACZ,qBAAA,KAAK,CAAC,CAAC,GAAG,KAAI;AACb,oBAAA,MAAM,CAAC,IAAI,KAAK,CAAC,8BAA8B,GAAG,CAAA,CAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;AACxE,gBAAA,CAAC;qBACA,OAAO,CAAC,MAAK;oBACZ,IAAI,EAAE,GAAG,EAAE;AACb,gBAAA,CAAC,CAAC;AACN,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;IAEO,MAAM,oBAAoB,CAC/B,UAAkB,EAClB,IAAqB,EACrB,OAAe,KAAK,EAAA;QAEpB,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,KAAI;AAClC,YAAA,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC;AACrD,QAAA,CAAC,CAAC;IACJ;AAEO,IAAA,MAAM,kBAAkB,CAC7B,IAAiB,EACjB,UAAkB,EAClB,IAAA,GAAsB,EAAE,KAAK,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,EAAA;QAEpD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;YACrC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,GAAG,EAAE,KAAK,KAAI;gBAC5C,IAAI,GAAG,EAAE;AACP,oBAAA,OAAO,MAAM,CAAC,GAAG,CAAC;gBACpB;AAEA,gBAAA,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;oBACxB,MAAM,QAAQ,GAAG,CAAA,EAAG,UAAU,IAAI,IAAI,CAAC,QAAQ,CAAA,CAAE;AACjD,oBAAA,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE;AAC5B,wBAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC/B,wBAAA,IAAI;4BACF,MAAM,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC;wBACrD;wBAAE,OAAO,KAAK,EAAE;4BACd,OAAO,MAAM,CAAC,KAAK,YAAY,KAAK,GAAG,KAAK,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;wBAC1E;oBACF;yBAAO;AACL,wBAAA,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC;oBAC3B;gBACF;gBACA,OAAO,CAAC,IAAI,CAAC;AACf,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;IAEO,KAAK,CAAC,IAAiB,EAAE,IAAY,EAAA;QAC1C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;AACrC,YAAA,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AAChE,QAAA,CAAC,CAAC;IACJ;IAEO,MAAM,CAAC,IAAiB,EAAE,IAAY,EAAA;QAC3C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;AACrC,YAAA,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,GAAG,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AACjE,QAAA,CAAC,CAAC;IACJ;IAEO,MAAM,YAAY,CAAC,IAAY,EAAA;QACpC,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,KAAI;AAClC,YAAA,IAAI;gBACF,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC;AACtD,gBAAA,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA,8CAAA,CAAgD,CAAC;gBAClE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA,gCAAA,EAAmC,IAAI,CAAC,KAAK,CAAA,CAAE,CAAC;gBACjE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA,sCAAA,EAAyC,IAAI,CAAC,WAAW,CAAA,CAAE,CAAC;AAE7E,gBAAA,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,KAAK,EAAE;oBACjC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA,6BAAA,EAAgC,QAAQ,CAAA,CAAE,CAAC;oBAC5D,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC;gBACnC;gBAEA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;AAEpD,gBAAA,KAAK,MAAM,aAAa,IAAI,IAAI,CAAC,WAAW,EAAE;oBAC5C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA,wBAAA,EAA2B,aAAa,CAAA,CAAE,CAAC;oBAC5D,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,aAAa,CAAC;gBACvC;gBAEA,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC;AAC5B,gBAAA,OAAO,IAAI;YACb;YAAE,OAAO,CAAU,EAAE;AACnB,gBAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;AACpB,gBAAA,MAAM,OAAO,GAAG,CAAC,YAAY,KAAK,GAAG,CAAC,CAAC,OAAO,GAAG,EAAE;gBACnD,MAAM,IAAI,KAAK,CAAC,CAAA,wBAAA,EAA2B,IAAI,CAAA,WAAA,EAAc,OAAO,CAAA,CAAE,CAAC;YACzE;AACF,QAAA,CAAC,CAAC;IACJ;IAEO,MAAM,QAAQ,CAAC,UAAkB,EAAA;QACtC,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,KAAI;YAClC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;gBACrC,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAI;oBACxC,IAAI,GAAG,EAAE;wBACP,OAAO,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,GAAG,CAAA,CAAE,CAAC,CAAC;oBAClD;AACA,oBAAA,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;AAC5B,gBAAA,CAAC,CAAC;AACJ,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;AAEA,IAAA,MAAM,KAAK,CAAC,IAAY,EAAE,IAAY,EAAA;QACpC,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,KAAI;YAClC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;gBACrC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,KAAI;oBAC7B,IAAI,GAAG,EAAE;AACP,wBAAA,OAAO,MAAM,CAAC,IAAI,KAAK,CAAC,CAAA,WAAA,EAAc,GAAG,CAAA,QAAA,EAAW,IAAI,CAAA,QAAA,EAAW,IAAI,CAAA,CAAE,CAAC,CAAC;oBAC7E;AACA,oBAAA,OAAO,OAAO,CAAC,SAAS,CAAC;AAC3B,gBAAA,CAAC,CAAC;AACJ,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;IAEA,MAAM,eAAe,CAAC,UAAkB,EAAA;QACtC,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,KAAI;YAClC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;gBACrC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,GAAsB,EAAE,KAAK,KAAI;oBACtD,IAAI,GAAG,EAAE;AACP,wBAAA,IAAK,GAAoC,EAAE,IAAI,KAAK,CAAC,EAAE;AACrD,4BAAA,OAAO,OAAO,CAAC,KAAK,CAAC;wBACvB;wBACA,OAAO,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,GAAG,CAAA,CAAE,CAAC,CAAC;oBAC7D;AACA,oBAAA,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;AACzB,gBAAA,CAAC,CAAC;AACJ,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;IAEA,MAAM,eAAe,CACnB,UAAkB,EAAA;QAElB,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,KAAI;YAClC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;gBACrC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,GAAG,EAAE,KAAK,KAAI;oBACnC,IAAI,GAAG,EAAE;AACP,wBAAA,IAAK,GAAgC,CAAC,IAAI,KAAK,CAAC,EAAE;AAChD,4BAAA,OAAO,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;wBACtE;wBACA,OAAO,MAAM,CAAC,IAAI,KAAK,CAAC,wBAAwB,GAAG,CAAA,CAAE,CAAC,CAAC;oBACzD;AACA,oBAAA,OAAO,CAAC;AACN,wBAAA,MAAM,EAAE,IAAI;AACZ,wBAAA,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE;AACtB,wBAAA,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE;AACjC,qBAAA,CAAC;AACJ,gBAAA,CAAC,CAAC;AACJ,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;IAEQ,MAAM,SAAS,CACrB,IAAiB,EACjB,UAAkB,EAClB,IAAqB,EACrB,IAAA,GAAe,KAAK,EAAA;QAEpB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;AACrC,YAAA,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,KAAI;gBACjD,IAAI,GAAG,EAAE;AACP,oBAAA,OAAO,MAAM,CAAC,IAAI,KAAK,CAAC,CAAA,mBAAA,EAAsB,GAAG,CAAA,cAAA,EAAiB,UAAU,CAAA,CAAE,CAAC,CAAC;gBAClF;gBACA,OAAO,CAAC,IAAI,CAAC;AACf,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;IAEO,2BAA2B,CAChC,IAAiB,EACjB,SAAiB,EACjB,UAAkB,EAClB,OAAe,KAAK,EAAA;QAEpB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;YACrC,KAAK,QAAQ,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,OAAO,MAAc,KAAI;gBACrD,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI;qBACjD,IAAI,CAAC,MAAK;oBACT,OAAO,CAAC,SAAS,CAAC;AACpB,gBAAA,CAAC;AACA,qBAAA,KAAK,CAAC,CAAC,GAAG,KAAI;AACb,oBAAA,MAAM,GAAG,GAAG,CAAA,6BAAA,EAAgC,GAAG,EAAE;AACjD,oBAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC;AACtB,oBAAA,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC;AACxB,gBAAA,CAAC,CAAC;AACN,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;IAEQ,MAAM,iBAAiB,CAC7B,IAAiB,EACjB,QAAgB,EAChB,SAAiB,EACjB,IAAA,GAAe,KAAK,EAAA;QAEpB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;YACrC,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,GAAG,EAAE,KAAK,KAAI;gBACxC,IAAI,GAAG,EAAE;AACP,oBAAA,OAAO,MAAM,CACX,IAAI,KAAK,CACP,CAAA,qBAAA,EAAwB,GAAG,CAAA,YAAA,EAAe,QAAQ,CAAA,aAAA,EAAgB,SAAS,CAAA,CAAE,CAC9E,CACF;gBACH;AAEA,gBAAA,IAAI;oBACF,MAAM,IAAI,CAAC,uBAAuB,CAAC,IAAI,EAAE,SAAS,CAAC;AACnD,oBAAA,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;wBACxB,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC;AAC5C,wBAAA,MAAM,UAAU,GAAG,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,IAAI,EAAE;wBAEzC,IAAI,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE;AACzC,4BAAA,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC;wBACjE;6BAAO;AACL,4BAAA,MAAM,IAAI,CAAC,2BAA2B,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC;wBAC3E;oBACF;AAEA,oBAAA,OAAO,EAAE;gBACX;gBAAE,OAAO,GAAG,EAAE;AACZ,oBAAA,MAAM,GAAG,GAAG,CAAA,6BAAA,EAAgC,GAAG,EAAE;AACjD,oBAAA,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC;AACtB,oBAAA,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC;gBACxB;AACF,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;AAEA;;;;;AAKG;IACI,MAAM,eAAe,CAC1B,QAAgB,EAChB,SAAiB,EACjB,OAAe,KAAK,EAAA;QAEpB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;YACrC,KAAK,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAiB,KAAI;AAC7C,gBAAA,IAAI;AACF,oBAAA,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC;AAC7D,oBAAA,OAAO,EAAE;gBACX;gBAAE,OAAO,CAAU,EAAE;oBACnB,MAAM,CAAC,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAA,CAAE,CAAC,CAAC;gBAChD;AACF,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;AAEA;;;;;AAKG;IACK,uBAAuB,CAAC,IAAiB,EAAE,UAAkB,EAAA;QACnE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;YACrC,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC;YACzC,IAAI,WAAW,GAAG,EAAE;AAEpB,YAAA,MAAM,UAAU,GAAG,CAAC,KAAa,KAAI;AACnC,gBAAA,IAAI,KAAK,IAAI,WAAW,CAAC,MAAM,EAAE;oBAC/B,OAAO,OAAO,EAAE;gBAClB;AAEA,gBAAA,WAAW,IAAI,CAAA,EAAG,WAAW,CAAC,KAAK,CAAC,GAAG;gBAEvC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,KAAI;oBAC7B,IAAI,GAAG,EAAE;wBACP,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,GAAG,KAAI;4BAC9B,IAAI,GAAG,EAAE;AACP,gCAAA,OAAO,MAAM,CACX,IAAI,KAAK,CAAC,CAAA,wBAAA,EAA2B,GAAG,CAAA,cAAA,EAAiB,UAAU,CAAA,CAAE,CAAC,CACvE;4BACH;AACA,4BAAA,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC;AACvB,wBAAA,CAAC,CAAC;oBACJ;yBAAO;AACL,wBAAA,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC;oBACvB;AACF,gBAAA,CAAC,CAAC;AACJ,YAAA,CAAC;YAED,UAAU,CAAC,CAAC,CAAC;AACf,QAAA,CAAC,CAAC;IACJ;AAEA;;;;;AAKG;AACI,IAAA,sBAAsB,CAAC,UAAkB,EAAE,IAAA,GAAe,KAAK,EAAA;QACpE,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,KAAI;YAClC,MAAM,WAAW,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC;YACzC,IAAI,WAAW,GAAG,EAAE;AAEpB,YAAA,KAAK,MAAM,SAAS,IAAI,WAAW,EAAE;AACnC,gBAAA,WAAW,IAAI,CAAA,EAAG,SAAS,CAAA,CAAA,CAAG;AAE9B,gBAAA,IAAI;oBACF,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,KAAI;wBAC1C,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,KAAI;AAC7B,4BAAA,IAAI,CAAC,GAAG;gCAAE,OAAO,OAAO,EAAE;AAE1B,4BAAA,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,KAAI;gCACxC,IAAI,GAAG,EAAE;AACP,oCAAA,OAAO,MAAM,CACX,IAAI,KAAK,CAAC,CAAA,yBAAA,EAA4B,GAAG,CAAA,cAAA,EAAiB,UAAU,CAAA,CAAE,CAAC,CACxE;gCACH;AACA,gCAAA,OAAO,EAAE;AACX,4BAAA,CAAC,CAAC;AACJ,wBAAA,CAAC,CAAC;AACJ,oBAAA,CAAC,CAAC;gBACJ;gBAAE,OAAO,KAAK,EAAE;oBACd,OAAO,CAAC,KAAK,CAAC,CAAA,4BAAA,EAA+B,WAAW,CAAA,CAAE,EAAE,KAAK,CAAC;AAClE,oBAAA,MAAM,KAAK;gBACb;YACF;AACF,QAAA,CAAC,CAAC;IACJ;AAEA;;;;;AAKG;AACI,IAAA,MAAM,YAAY,CAAC,UAAkB,EAAE,SAAiB,EAAA;QAC7D,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,KAAI;YAClC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;gBACrC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,CAAC,GAAG,KAAI;oBAC1C,IAAI,GAAG,EAAE;AACP,wBAAA,OAAO,MAAM,CACX,IAAI,KAAK,CACP,CAAA,sBAAA,EAAyB,GAAG,CAAA,cAAA,EAAiB,UAAU,CAAA,aAAA,EAAgB,SAAS,CAAA,CAAE,CACnF,CACF;oBACH;oBACA,OAAO,CAAC,IAAI,CAAC;AACf,gBAAA,CAAC,CAAC;AACJ,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;IACJ;AAEA;;AAEG;IACI,KAAK,GAAA;QACV,IAAI,CAAC,mBAAmB,EAAE;AAC1B,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE;IACnB;AACD;AAID,eAAe,OAAO,CACpB,MAAc,EACd,MAAqB,EACrB,OAA6B,EAC7B,OAAmB,EAAA;IAEnB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;AACrC,QAAA,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAK;YACtB,OAAO,CAAC,MAAM,CAAC;AACjB,QAAA,CAAC,CAAC;QAEF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAY,KAAI;YAElC,MAAM,CAAC,IAAI,KAAK,CAAC,gBAAgB,GAAG,CAAA,CAAE,CAAC,CAAC;AAC1C,QAAA,CAAC,CAAC;AAEF,QAAA,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAK;AAExB,QAAA,CAAC,CAAC;AAEF,QAAA,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;;;;;;AAOrB,QAAA,MAAc,CAAC,UAAU,CAAC,IAAI,CAAC;AAClC,IAAA,CAAC,CAAC;AACJ;AAEA,eAAe,UAAU,CACvB,MAAgB,EAChB,IAAY,EACZ,SAAiB,EACjB,SAAiB,EACjB,UAAkB,EAClB,UAAkB,EAAA;IAElB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,KAAI;AACrC,QAAA,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAI;YAC5E,IAAI,GAAG,EAAE;AACP,gBAAA,MAAM,CAAC,KAAK,CAAC,qBAAqB,GAAG,CAAA,CAAE,CAAC;AACxC,gBAAA,OAAO,MAAM,CAAC,GAAG,CAAC;YACpB;AAEA,YAAA,OAAO,OAAO,CAAC,MAAM,CAAC;AACxB,QAAA,CAAC,CAAC;AACJ,IAAA,CAAC,CAAC;AACJ;;;;"}
@@ -4,7 +4,7 @@ var tsHelpers = require('@milaboratories/ts-helpers');
4
4
 
5
5
  const MAX_UNWRAP_DEPTH = 10;
6
6
  class SSHError extends Error {
7
- name = 'SSHError';
7
+ name = "SSHError";
8
8
  constructor(messageOrErr, opts) {
9
9
  if (messageOrErr instanceof Error) {
10
10
  super(`SSHError: ${messageOrErr.message}`, { cause: opts?.cause ?? messageOrErr });
@@ -19,7 +19,7 @@ class SSHError extends Error {
19
19
  }
20
20
  class SFTPError extends SSHError {
21
21
  code;
22
- name = 'SFTPError';
22
+ name = "SFTPError";
23
23
  constructor(code, // raw SFTP error code, i.e. from OpenSSH server
24
24
  opts) {
25
25
  super(code, opts);
@@ -40,15 +40,17 @@ class SFTPError extends SSHError {
40
40
  // OpenSSH server returns this message in case of general failure.
41
41
  // See https://github.com/openssh/openssh-portable/blob/1cc936b2fabffeac7fff14ca1070d7d7a317ab7b/sftp-server.c#L244
42
42
  // See https://github.com/openssh/openssh-portable/blob/1cc936b2fabffeac7fff14ca1070d7d7a317ab7b/sftp-common.c#L195
43
- return this.code === 'Failure';
43
+ return this.code === "Failure";
44
44
  }
45
45
  }
46
46
  class SFTPUploadError extends SSHError {
47
47
  localPath;
48
48
  remotePath;
49
- name = 'SFTPUploadError';
49
+ name = "SFTPUploadError";
50
50
  constructor(err, localPath, remotePath) {
51
- super(`ssh.uploadFile: ${err.message}, localPath: ${localPath}, remotePath: ${remotePath}`, { cause: SFTPError.wrap(err) });
51
+ super(`ssh.uploadFile: ${err.message}, localPath: ${localPath}, remotePath: ${remotePath}`, {
52
+ cause: SFTPError.wrap(err),
53
+ });
52
54
  this.localPath = localPath;
53
55
  this.remotePath = remotePath;
54
56
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ssh_errors.cjs","sources":["../../src/ssh/ssh_errors.ts"],"sourcesContent":["import { findNamedErrorInCauses } from '@milaboratories/ts-helpers';\n\nconst MAX_UNWRAP_DEPTH = 10;\n\nexport class SSHError extends Error {\n name = 'SSHError';\n\n constructor(message: string, opts?: { cause: Error });\n constructor(err: Error);\n constructor(messageOrErr: string | Error, opts?: { cause: Error }) {\n if (messageOrErr instanceof Error) {\n super(`SSHError: ${messageOrErr.message}`, { cause: opts?.cause ?? messageOrErr });\n } else {\n super(`SSHError: ${messageOrErr}`, opts);\n }\n }\n\n static from(err: unknown): SSHError | undefined {\n return findNamedErrorInCauses(err, SSHError, MAX_UNWRAP_DEPTH);\n }\n}\n\nexport class SFTPError extends SSHError {\n name = 'SFTPError';\n\n constructor(\n public readonly code: string, // raw SFTP error code, i.e. from OpenSSH server\n opts?: { cause: Error },\n ) {\n super(code, opts);\n }\n\n /** Optionally wraps an error into SFTPError, if it is not already of this type */\n static wrap(err: Error): SFTPError;\n static wrap(err: undefined): undefined;\n static wrap(err: Error | undefined): SFTPError | undefined {\n if (!err) return undefined;\n const sftpErr = SFTPError.from(err);\n if (sftpErr) return sftpErr;\n return new SFTPError(err.message, { cause: err });\n }\n\n static from(err: unknown): SFTPError | undefined {\n return findNamedErrorInCauses(err, SFTPError, MAX_UNWRAP_DEPTH);\n }\n\n public get isGenericFailure(): boolean {\n // OpenSSH server returns this message in case of general failure.\n // See https://github.com/openssh/openssh-portable/blob/1cc936b2fabffeac7fff14ca1070d7d7a317ab7b/sftp-server.c#L244\n // See https://github.com/openssh/openssh-portable/blob/1cc936b2fabffeac7fff14ca1070d7d7a317ab7b/sftp-common.c#L195\n return this.code === 'Failure';\n }\n}\n\nexport class SFTPUploadError extends SSHError {\n name = 'SFTPUploadError';\n\n constructor(\n err: Error,\n public readonly localPath: string,\n public readonly remotePath: string,\n ) {\n super(`ssh.uploadFile: ${err.message}, localPath: ${localPath}, remotePath: ${remotePath}`, { cause: SFTPError.wrap(err) });\n }\n\n static from(err: unknown): SFTPUploadError | undefined {\n return findNamedErrorInCauses(err, SFTPUploadError, MAX_UNWRAP_DEPTH);\n }\n}\n"],"names":["findNamedErrorInCauses"],"mappings":";;;;AAEA,MAAM,gBAAgB,GAAG,EAAE;AAErB,MAAO,QAAS,SAAQ,KAAK,CAAA;IACjC,IAAI,GAAG,UAAU;IAIjB,WAAA,CAAY,YAA4B,EAAE,IAAuB,EAAA;AAC/D,QAAA,IAAI,YAAY,YAAY,KAAK,EAAE;AACjC,YAAA,KAAK,CAAC,CAAA,UAAA,EAAa,YAAY,CAAC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,YAAY,EAAE,CAAC;QACpF;aAAO;AACL,YAAA,KAAK,CAAC,CAAA,UAAA,EAAa,YAAY,EAAE,EAAE,IAAI,CAAC;QAC1C;IACF;IAEA,OAAO,IAAI,CAAC,GAAY,EAAA;QACtB,OAAOA,gCAAsB,CAAC,GAAG,EAAE,QAAQ,EAAE,gBAAgB,CAAC;IAChE;AACD;AAEK,MAAO,SAAU,SAAQ,QAAQ,CAAA;AAInB,IAAA,IAAA;IAHlB,IAAI,GAAG,WAAW;IAElB,WAAA,CACkB,IAAY;IAC5B,IAAuB,EAAA;AAEvB,QAAA,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC;QAHD,IAAA,CAAA,IAAI,GAAJ,IAAI;IAItB;IAKA,OAAO,IAAI,CAAC,GAAsB,EAAA;AAChC,QAAA,IAAI,CAAC,GAAG;AAAE,YAAA,OAAO,SAAS;QAC1B,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;AACnC,QAAA,IAAI,OAAO;AAAE,YAAA,OAAO,OAAO;AAC3B,QAAA,OAAO,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IACnD;IAEA,OAAO,IAAI,CAAC,GAAY,EAAA;QACtB,OAAOA,gCAAsB,CAAC,GAAG,EAAE,SAAS,EAAE,gBAAgB,CAAC;IACjE;AAEA,IAAA,IAAW,gBAAgB,GAAA;;;;AAIzB,QAAA,OAAO,IAAI,CAAC,IAAI,KAAK,SAAS;IAChC;AACD;AAEK,MAAO,eAAgB,SAAQ,QAAQ,CAAA;AAKzB,IAAA,SAAA;AACA,IAAA,UAAA;IALlB,IAAI,GAAG,iBAAiB;AAExB,IAAA,WAAA,CACE,GAAU,EACM,SAAiB,EACjB,UAAkB,EAAA;QAElC,KAAK,CAAC,mBAAmB,GAAG,CAAC,OAAO,CAAA,aAAA,EAAgB,SAAS,CAAA,cAAA,EAAiB,UAAU,CAAA,CAAE,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAH3G,IAAA,CAAA,SAAS,GAAT,SAAS;QACT,IAAA,CAAA,UAAU,GAAV,UAAU;IAG5B;IAEA,OAAO,IAAI,CAAC,GAAY,EAAA;QACtB,OAAOA,gCAAsB,CAAC,GAAG,EAAE,eAAe,EAAE,gBAAgB,CAAC;IACvE;AACD;;;;;;"}
1
+ {"version":3,"file":"ssh_errors.cjs","sources":["../../src/ssh/ssh_errors.ts"],"sourcesContent":["import { findNamedErrorInCauses } from \"@milaboratories/ts-helpers\";\n\nconst MAX_UNWRAP_DEPTH = 10;\n\nexport class SSHError extends Error {\n name = \"SSHError\";\n\n constructor(message: string, opts?: { cause: Error });\n constructor(err: Error);\n constructor(messageOrErr: string | Error, opts?: { cause: Error }) {\n if (messageOrErr instanceof Error) {\n super(`SSHError: ${messageOrErr.message}`, { cause: opts?.cause ?? messageOrErr });\n } else {\n super(`SSHError: ${messageOrErr}`, opts);\n }\n }\n\n static from(err: unknown): SSHError | undefined {\n return findNamedErrorInCauses(err, SSHError, MAX_UNWRAP_DEPTH);\n }\n}\n\nexport class SFTPError extends SSHError {\n name = \"SFTPError\";\n\n constructor(\n public readonly code: string, // raw SFTP error code, i.e. from OpenSSH server\n opts?: { cause: Error },\n ) {\n super(code, opts);\n }\n\n /** Optionally wraps an error into SFTPError, if it is not already of this type */\n static wrap(err: Error): SFTPError;\n static wrap(err: undefined): undefined;\n static wrap(err: Error | undefined): SFTPError | undefined {\n if (!err) return undefined;\n const sftpErr = SFTPError.from(err);\n if (sftpErr) return sftpErr;\n return new SFTPError(err.message, { cause: err });\n }\n\n static from(err: unknown): SFTPError | undefined {\n return findNamedErrorInCauses(err, SFTPError, MAX_UNWRAP_DEPTH);\n }\n\n public get isGenericFailure(): boolean {\n // OpenSSH server returns this message in case of general failure.\n // See https://github.com/openssh/openssh-portable/blob/1cc936b2fabffeac7fff14ca1070d7d7a317ab7b/sftp-server.c#L244\n // See https://github.com/openssh/openssh-portable/blob/1cc936b2fabffeac7fff14ca1070d7d7a317ab7b/sftp-common.c#L195\n return this.code === \"Failure\";\n }\n}\n\nexport class SFTPUploadError extends SSHError {\n name = \"SFTPUploadError\";\n\n constructor(\n err: Error,\n public readonly localPath: string,\n public readonly remotePath: string,\n ) {\n super(`ssh.uploadFile: ${err.message}, localPath: ${localPath}, remotePath: ${remotePath}`, {\n cause: SFTPError.wrap(err),\n });\n }\n\n static from(err: unknown): SFTPUploadError | undefined {\n return findNamedErrorInCauses(err, SFTPUploadError, MAX_UNWRAP_DEPTH);\n }\n}\n"],"names":["findNamedErrorInCauses"],"mappings":";;;;AAEA,MAAM,gBAAgB,GAAG,EAAE;AAErB,MAAO,QAAS,SAAQ,KAAK,CAAA;IACjC,IAAI,GAAG,UAAU;IAIjB,WAAA,CAAY,YAA4B,EAAE,IAAuB,EAAA;AAC/D,QAAA,IAAI,YAAY,YAAY,KAAK,EAAE;AACjC,YAAA,KAAK,CAAC,CAAA,UAAA,EAAa,YAAY,CAAC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,YAAY,EAAE,CAAC;QACpF;aAAO;AACL,YAAA,KAAK,CAAC,CAAA,UAAA,EAAa,YAAY,EAAE,EAAE,IAAI,CAAC;QAC1C;IACF;IAEA,OAAO,IAAI,CAAC,GAAY,EAAA;QACtB,OAAOA,gCAAsB,CAAC,GAAG,EAAE,QAAQ,EAAE,gBAAgB,CAAC;IAChE;AACD;AAEK,MAAO,SAAU,SAAQ,QAAQ,CAAA;AAInB,IAAA,IAAA;IAHlB,IAAI,GAAG,WAAW;IAElB,WAAA,CACkB,IAAY;IAC5B,IAAuB,EAAA;AAEvB,QAAA,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC;QAHD,IAAA,CAAA,IAAI,GAAJ,IAAI;IAItB;IAKA,OAAO,IAAI,CAAC,GAAsB,EAAA;AAChC,QAAA,IAAI,CAAC,GAAG;AAAE,YAAA,OAAO,SAAS;QAC1B,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;AACnC,QAAA,IAAI,OAAO;AAAE,YAAA,OAAO,OAAO;AAC3B,QAAA,OAAO,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IACnD;IAEA,OAAO,IAAI,CAAC,GAAY,EAAA;QACtB,OAAOA,gCAAsB,CAAC,GAAG,EAAE,SAAS,EAAE,gBAAgB,CAAC;IACjE;AAEA,IAAA,IAAW,gBAAgB,GAAA;;;;AAIzB,QAAA,OAAO,IAAI,CAAC,IAAI,KAAK,SAAS;IAChC;AACD;AAEK,MAAO,eAAgB,SAAQ,QAAQ,CAAA;AAKzB,IAAA,SAAA;AACA,IAAA,UAAA;IALlB,IAAI,GAAG,iBAAiB;AAExB,IAAA,WAAA,CACE,GAAU,EACM,SAAiB,EACjB,UAAkB,EAAA;QAElC,KAAK,CAAC,CAAA,gBAAA,EAAmB,GAAG,CAAC,OAAO,gBAAgB,SAAS,CAAA,cAAA,EAAiB,UAAU,CAAA,CAAE,EAAE;AAC1F,YAAA,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;AAC3B,SAAA,CAAC;QALc,IAAA,CAAA,SAAS,GAAT,SAAS;QACT,IAAA,CAAA,UAAU,GAAV,UAAU;IAK5B;IAEA,OAAO,IAAI,CAAC,GAAY,EAAA;QACtB,OAAOA,gCAAsB,CAAC,GAAG,EAAE,eAAe,EAAE,gBAAgB,CAAC;IACvE;AACD;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"ssh_errors.d.ts","sourceRoot":"","sources":["../../src/ssh/ssh_errors.ts"],"names":[],"mappings":"AAIA,qBAAa,QAAS,SAAQ,KAAK;IACjC,IAAI,SAAc;gBAEN,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,EAAE,KAAK,CAAA;KAAE;gBACxC,GAAG,EAAE,KAAK;IAStB,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS;CAGhD;AAED,qBAAa,SAAU,SAAQ,QAAQ;aAInB,IAAI,EAAE,MAAM;IAH9B,IAAI,SAAe;gBAGD,IAAI,EAAE,MAAM,EAAE,gDAAgD;IAC9E,IAAI,CAAC,EAAE;QAAE,KAAK,EAAE,KAAK,CAAA;KAAE;IAKzB,kFAAkF;IAClF,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,GAAG,SAAS;IAClC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,GAAG,SAAS;IAQtC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS;IAIhD,IAAW,gBAAgB,IAAI,OAAO,CAKrC;CACF;AAED,qBAAa,eAAgB,SAAQ,QAAQ;aAKzB,SAAS,EAAE,MAAM;aACjB,UAAU,EAAE,MAAM;IALpC,IAAI,SAAqB;gBAGvB,GAAG,EAAE,KAAK,EACM,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM;IAKpC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,GAAG,eAAe,GAAG,SAAS;CAGvD"}
1
+ {"version":3,"file":"ssh_errors.d.ts","sourceRoot":"","sources":["../../src/ssh/ssh_errors.ts"],"names":[],"mappings":"AAIA,qBAAa,QAAS,SAAQ,KAAK;IACjC,IAAI,SAAc;gBAEN,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,KAAK,EAAE,KAAK,CAAA;KAAE;gBACxC,GAAG,EAAE,KAAK;IAStB,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS;CAGhD;AAED,qBAAa,SAAU,SAAQ,QAAQ;aAInB,IAAI,EAAE,MAAM;IAH9B,IAAI,SAAe;gBAGD,IAAI,EAAE,MAAM,EAAE,gDAAgD;IAC9E,IAAI,CAAC,EAAE;QAAE,KAAK,EAAE,KAAK,CAAA;KAAE;IAKzB,kFAAkF;IAClF,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,GAAG,SAAS;IAClC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,GAAG,SAAS;IAQtC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS;IAIhD,IAAW,gBAAgB,IAAI,OAAO,CAKrC;CACF;AAED,qBAAa,eAAgB,SAAQ,QAAQ;aAKzB,SAAS,EAAE,MAAM;aACjB,UAAU,EAAE,MAAM;IALpC,IAAI,SAAqB;gBAGvB,GAAG,EAAE,KAAK,EACM,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM;IAOpC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,GAAG,eAAe,GAAG,SAAS;CAGvD"}
@@ -2,7 +2,7 @@ import { findNamedErrorInCauses } from '@milaboratories/ts-helpers';
2
2
 
3
3
  const MAX_UNWRAP_DEPTH = 10;
4
4
  class SSHError extends Error {
5
- name = 'SSHError';
5
+ name = "SSHError";
6
6
  constructor(messageOrErr, opts) {
7
7
  if (messageOrErr instanceof Error) {
8
8
  super(`SSHError: ${messageOrErr.message}`, { cause: opts?.cause ?? messageOrErr });
@@ -17,7 +17,7 @@ class SSHError extends Error {
17
17
  }
18
18
  class SFTPError extends SSHError {
19
19
  code;
20
- name = 'SFTPError';
20
+ name = "SFTPError";
21
21
  constructor(code, // raw SFTP error code, i.e. from OpenSSH server
22
22
  opts) {
23
23
  super(code, opts);
@@ -38,15 +38,17 @@ class SFTPError extends SSHError {
38
38
  // OpenSSH server returns this message in case of general failure.
39
39
  // See https://github.com/openssh/openssh-portable/blob/1cc936b2fabffeac7fff14ca1070d7d7a317ab7b/sftp-server.c#L244
40
40
  // See https://github.com/openssh/openssh-portable/blob/1cc936b2fabffeac7fff14ca1070d7d7a317ab7b/sftp-common.c#L195
41
- return this.code === 'Failure';
41
+ return this.code === "Failure";
42
42
  }
43
43
  }
44
44
  class SFTPUploadError extends SSHError {
45
45
  localPath;
46
46
  remotePath;
47
- name = 'SFTPUploadError';
47
+ name = "SFTPUploadError";
48
48
  constructor(err, localPath, remotePath) {
49
- super(`ssh.uploadFile: ${err.message}, localPath: ${localPath}, remotePath: ${remotePath}`, { cause: SFTPError.wrap(err) });
49
+ super(`ssh.uploadFile: ${err.message}, localPath: ${localPath}, remotePath: ${remotePath}`, {
50
+ cause: SFTPError.wrap(err),
51
+ });
50
52
  this.localPath = localPath;
51
53
  this.remotePath = remotePath;
52
54
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ssh_errors.js","sources":["../../src/ssh/ssh_errors.ts"],"sourcesContent":["import { findNamedErrorInCauses } from '@milaboratories/ts-helpers';\n\nconst MAX_UNWRAP_DEPTH = 10;\n\nexport class SSHError extends Error {\n name = 'SSHError';\n\n constructor(message: string, opts?: { cause: Error });\n constructor(err: Error);\n constructor(messageOrErr: string | Error, opts?: { cause: Error }) {\n if (messageOrErr instanceof Error) {\n super(`SSHError: ${messageOrErr.message}`, { cause: opts?.cause ?? messageOrErr });\n } else {\n super(`SSHError: ${messageOrErr}`, opts);\n }\n }\n\n static from(err: unknown): SSHError | undefined {\n return findNamedErrorInCauses(err, SSHError, MAX_UNWRAP_DEPTH);\n }\n}\n\nexport class SFTPError extends SSHError {\n name = 'SFTPError';\n\n constructor(\n public readonly code: string, // raw SFTP error code, i.e. from OpenSSH server\n opts?: { cause: Error },\n ) {\n super(code, opts);\n }\n\n /** Optionally wraps an error into SFTPError, if it is not already of this type */\n static wrap(err: Error): SFTPError;\n static wrap(err: undefined): undefined;\n static wrap(err: Error | undefined): SFTPError | undefined {\n if (!err) return undefined;\n const sftpErr = SFTPError.from(err);\n if (sftpErr) return sftpErr;\n return new SFTPError(err.message, { cause: err });\n }\n\n static from(err: unknown): SFTPError | undefined {\n return findNamedErrorInCauses(err, SFTPError, MAX_UNWRAP_DEPTH);\n }\n\n public get isGenericFailure(): boolean {\n // OpenSSH server returns this message in case of general failure.\n // See https://github.com/openssh/openssh-portable/blob/1cc936b2fabffeac7fff14ca1070d7d7a317ab7b/sftp-server.c#L244\n // See https://github.com/openssh/openssh-portable/blob/1cc936b2fabffeac7fff14ca1070d7d7a317ab7b/sftp-common.c#L195\n return this.code === 'Failure';\n }\n}\n\nexport class SFTPUploadError extends SSHError {\n name = 'SFTPUploadError';\n\n constructor(\n err: Error,\n public readonly localPath: string,\n public readonly remotePath: string,\n ) {\n super(`ssh.uploadFile: ${err.message}, localPath: ${localPath}, remotePath: ${remotePath}`, { cause: SFTPError.wrap(err) });\n }\n\n static from(err: unknown): SFTPUploadError | undefined {\n return findNamedErrorInCauses(err, SFTPUploadError, MAX_UNWRAP_DEPTH);\n }\n}\n"],"names":[],"mappings":";;AAEA,MAAM,gBAAgB,GAAG,EAAE;AAErB,MAAO,QAAS,SAAQ,KAAK,CAAA;IACjC,IAAI,GAAG,UAAU;IAIjB,WAAA,CAAY,YAA4B,EAAE,IAAuB,EAAA;AAC/D,QAAA,IAAI,YAAY,YAAY,KAAK,EAAE;AACjC,YAAA,KAAK,CAAC,CAAA,UAAA,EAAa,YAAY,CAAC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,YAAY,EAAE,CAAC;QACpF;aAAO;AACL,YAAA,KAAK,CAAC,CAAA,UAAA,EAAa,YAAY,EAAE,EAAE,IAAI,CAAC;QAC1C;IACF;IAEA,OAAO,IAAI,CAAC,GAAY,EAAA;QACtB,OAAO,sBAAsB,CAAC,GAAG,EAAE,QAAQ,EAAE,gBAAgB,CAAC;IAChE;AACD;AAEK,MAAO,SAAU,SAAQ,QAAQ,CAAA;AAInB,IAAA,IAAA;IAHlB,IAAI,GAAG,WAAW;IAElB,WAAA,CACkB,IAAY;IAC5B,IAAuB,EAAA;AAEvB,QAAA,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC;QAHD,IAAA,CAAA,IAAI,GAAJ,IAAI;IAItB;IAKA,OAAO,IAAI,CAAC,GAAsB,EAAA;AAChC,QAAA,IAAI,CAAC,GAAG;AAAE,YAAA,OAAO,SAAS;QAC1B,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;AACnC,QAAA,IAAI,OAAO;AAAE,YAAA,OAAO,OAAO;AAC3B,QAAA,OAAO,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IACnD;IAEA,OAAO,IAAI,CAAC,GAAY,EAAA;QACtB,OAAO,sBAAsB,CAAC,GAAG,EAAE,SAAS,EAAE,gBAAgB,CAAC;IACjE;AAEA,IAAA,IAAW,gBAAgB,GAAA;;;;AAIzB,QAAA,OAAO,IAAI,CAAC,IAAI,KAAK,SAAS;IAChC;AACD;AAEK,MAAO,eAAgB,SAAQ,QAAQ,CAAA;AAKzB,IAAA,SAAA;AACA,IAAA,UAAA;IALlB,IAAI,GAAG,iBAAiB;AAExB,IAAA,WAAA,CACE,GAAU,EACM,SAAiB,EACjB,UAAkB,EAAA;QAElC,KAAK,CAAC,mBAAmB,GAAG,CAAC,OAAO,CAAA,aAAA,EAAgB,SAAS,CAAA,cAAA,EAAiB,UAAU,CAAA,CAAE,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAH3G,IAAA,CAAA,SAAS,GAAT,SAAS;QACT,IAAA,CAAA,UAAU,GAAV,UAAU;IAG5B;IAEA,OAAO,IAAI,CAAC,GAAY,EAAA;QACtB,OAAO,sBAAsB,CAAC,GAAG,EAAE,eAAe,EAAE,gBAAgB,CAAC;IACvE;AACD;;;;"}
1
+ {"version":3,"file":"ssh_errors.js","sources":["../../src/ssh/ssh_errors.ts"],"sourcesContent":["import { findNamedErrorInCauses } from \"@milaboratories/ts-helpers\";\n\nconst MAX_UNWRAP_DEPTH = 10;\n\nexport class SSHError extends Error {\n name = \"SSHError\";\n\n constructor(message: string, opts?: { cause: Error });\n constructor(err: Error);\n constructor(messageOrErr: string | Error, opts?: { cause: Error }) {\n if (messageOrErr instanceof Error) {\n super(`SSHError: ${messageOrErr.message}`, { cause: opts?.cause ?? messageOrErr });\n } else {\n super(`SSHError: ${messageOrErr}`, opts);\n }\n }\n\n static from(err: unknown): SSHError | undefined {\n return findNamedErrorInCauses(err, SSHError, MAX_UNWRAP_DEPTH);\n }\n}\n\nexport class SFTPError extends SSHError {\n name = \"SFTPError\";\n\n constructor(\n public readonly code: string, // raw SFTP error code, i.e. from OpenSSH server\n opts?: { cause: Error },\n ) {\n super(code, opts);\n }\n\n /** Optionally wraps an error into SFTPError, if it is not already of this type */\n static wrap(err: Error): SFTPError;\n static wrap(err: undefined): undefined;\n static wrap(err: Error | undefined): SFTPError | undefined {\n if (!err) return undefined;\n const sftpErr = SFTPError.from(err);\n if (sftpErr) return sftpErr;\n return new SFTPError(err.message, { cause: err });\n }\n\n static from(err: unknown): SFTPError | undefined {\n return findNamedErrorInCauses(err, SFTPError, MAX_UNWRAP_DEPTH);\n }\n\n public get isGenericFailure(): boolean {\n // OpenSSH server returns this message in case of general failure.\n // See https://github.com/openssh/openssh-portable/blob/1cc936b2fabffeac7fff14ca1070d7d7a317ab7b/sftp-server.c#L244\n // See https://github.com/openssh/openssh-portable/blob/1cc936b2fabffeac7fff14ca1070d7d7a317ab7b/sftp-common.c#L195\n return this.code === \"Failure\";\n }\n}\n\nexport class SFTPUploadError extends SSHError {\n name = \"SFTPUploadError\";\n\n constructor(\n err: Error,\n public readonly localPath: string,\n public readonly remotePath: string,\n ) {\n super(`ssh.uploadFile: ${err.message}, localPath: ${localPath}, remotePath: ${remotePath}`, {\n cause: SFTPError.wrap(err),\n });\n }\n\n static from(err: unknown): SFTPUploadError | undefined {\n return findNamedErrorInCauses(err, SFTPUploadError, MAX_UNWRAP_DEPTH);\n }\n}\n"],"names":[],"mappings":";;AAEA,MAAM,gBAAgB,GAAG,EAAE;AAErB,MAAO,QAAS,SAAQ,KAAK,CAAA;IACjC,IAAI,GAAG,UAAU;IAIjB,WAAA,CAAY,YAA4B,EAAE,IAAuB,EAAA;AAC/D,QAAA,IAAI,YAAY,YAAY,KAAK,EAAE;AACjC,YAAA,KAAK,CAAC,CAAA,UAAA,EAAa,YAAY,CAAC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,IAAI,YAAY,EAAE,CAAC;QACpF;aAAO;AACL,YAAA,KAAK,CAAC,CAAA,UAAA,EAAa,YAAY,EAAE,EAAE,IAAI,CAAC;QAC1C;IACF;IAEA,OAAO,IAAI,CAAC,GAAY,EAAA;QACtB,OAAO,sBAAsB,CAAC,GAAG,EAAE,QAAQ,EAAE,gBAAgB,CAAC;IAChE;AACD;AAEK,MAAO,SAAU,SAAQ,QAAQ,CAAA;AAInB,IAAA,IAAA;IAHlB,IAAI,GAAG,WAAW;IAElB,WAAA,CACkB,IAAY;IAC5B,IAAuB,EAAA;AAEvB,QAAA,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC;QAHD,IAAA,CAAA,IAAI,GAAJ,IAAI;IAItB;IAKA,OAAO,IAAI,CAAC,GAAsB,EAAA;AAChC,QAAA,IAAI,CAAC,GAAG;AAAE,YAAA,OAAO,SAAS;QAC1B,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;AACnC,QAAA,IAAI,OAAO;AAAE,YAAA,OAAO,OAAO;AAC3B,QAAA,OAAO,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;IACnD;IAEA,OAAO,IAAI,CAAC,GAAY,EAAA;QACtB,OAAO,sBAAsB,CAAC,GAAG,EAAE,SAAS,EAAE,gBAAgB,CAAC;IACjE;AAEA,IAAA,IAAW,gBAAgB,GAAA;;;;AAIzB,QAAA,OAAO,IAAI,CAAC,IAAI,KAAK,SAAS;IAChC;AACD;AAEK,MAAO,eAAgB,SAAQ,QAAQ,CAAA;AAKzB,IAAA,SAAA;AACA,IAAA,UAAA;IALlB,IAAI,GAAG,iBAAiB;AAExB,IAAA,WAAA,CACE,GAAU,EACM,SAAiB,EACjB,UAAkB,EAAA;QAElC,KAAK,CAAC,CAAA,gBAAA,EAAmB,GAAG,CAAC,OAAO,gBAAgB,SAAS,CAAA,cAAA,EAAiB,UAAU,CAAA,CAAE,EAAE;AAC1F,YAAA,KAAK,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;AAC3B,SAAA,CAAC;QALc,IAAA,CAAA,SAAS,GAAT,SAAS;QACT,IAAA,CAAA,UAAU,GAAV,UAAU;IAK5B;IAEA,OAAO,IAAI,CAAC,GAAY,EAAA;QACtB,OAAO,sBAAsB,CAAC,GAAG,EAAE,eAAe,EAAE,gBAAgB,CAAC;IACvE;AACD;;;;"}