@axinom/mosaic-cli 0.62.0-rc.4 → 0.62.0-rc.5

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.
@@ -3,6 +3,7 @@ import { isNullOrWhitespace } from '@axinom/mosaic-service-common';
3
3
  import axios, { AxiosError } from 'axios';
4
4
  import chalk from 'chalk';
5
5
  import net from 'net';
6
+ import ora from 'ora';
6
7
  import WebSocket, { createWebSocketStream } from 'ws';
7
8
  import { exitCode } from '../../../../common/index.js';
8
9
  const { red, yellow, green, dim, bold } = chalk;
@@ -48,6 +49,8 @@ export const formatClampedTtlWarning = (requestedMinutes, expiresAt, now = Date.
48
49
  return `Requested ${requestedMinutes} minutes, granted ${granted} - database access for this service expires then.`;
49
50
  };
50
51
  export const WARN_BEFORE_EXPIRY_MS = 5 * 60_000;
52
+ /** The byte a terminal delivers for Ctrl+C once it stops raising SIGINT. */
53
+ const ETX = 0x03;
51
54
  /** Undefined when the session is too short for the warning to precede it. */
52
55
  export const toExpiryWarningDelay = (expiresAt, now = Date.now()) => {
53
56
  const remaining = new Date(expiresAt).getTime() - now;
@@ -189,11 +192,56 @@ const listen = (server, port) => new Promise((resolve, reject) => {
189
192
  resolve();
190
193
  });
191
194
  });
192
- export const proxyDatabase = async (args) => {
193
- const port = args.localProxyPort ?? DEFAULT_LOCAL_PROXY_PORT;
194
- const hostingServiceBaseUrl = args.hostingServiceBaseURL;
195
- const getToken = createTokenProvider(args.idServiceAuthBaseURL, args.mosaicHostingClientId, args.mosaicHostingClientSecret);
196
- let session;
195
+ /** Hands the terminal back; the mode belongs to it, not to this process. */
196
+ const restoreStdinMode = () => {
197
+ if (process.stdin.isTTY && process.stdin.isRaw) {
198
+ process.stdin.setRawMode(false);
199
+ process.stdin.pause();
200
+ }
201
+ };
202
+ /**
203
+ * Calls `onShutdown` once, on Ctrl+C or a termination signal.
204
+ *
205
+ * Ctrl+C is read from stdin rather than taken as a signal: in raw mode the
206
+ * terminal stops raising one, which keeps it from also killing the `yarn` and
207
+ * `env-cmd` wrappers a solution runs this through. They would exit at once and
208
+ * hand the shell prompt back while the session was still closing.
209
+ */
210
+ const onShutdownRequested = (onShutdown) => {
211
+ let requested = false;
212
+ const request = () => {
213
+ if (requested) {
214
+ return;
215
+ }
216
+ requested = true;
217
+ onShutdown();
218
+ };
219
+ process.on('exit', restoreStdinMode);
220
+ // The baseline everywhere: `kill`, a shutting-down machine, Ctrl+Break, and
221
+ // any stdin that is not a terminal. SIGKILL cannot be caught; that falls to
222
+ // the session's expiry.
223
+ for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP', 'SIGBREAK']) {
224
+ process.on(signal, request);
225
+ }
226
+ // On a terminal, take the key before it becomes a SIGINT that would kill the
227
+ // wrappers too. Raw mode suppresses that signal on every platform.
228
+ if (process.stdin.isTTY) {
229
+ process.stdin.setRawMode(true);
230
+ process.stdin.resume();
231
+ process.stdin.on('data', (chunk) => {
232
+ if (chunk.includes(ETX)) {
233
+ request();
234
+ }
235
+ });
236
+ }
237
+ };
238
+ const openSession = async (args, hostingServiceBaseUrl, getToken) => {
239
+ // Creating the role is a remote call that regularly takes half a minute.
240
+ const spinner = ora({
241
+ text: `Opening a database access session for [${args.serviceId}]...`,
242
+ // Off: it would put stdin in raw mode, which is this command's to manage.
243
+ discardStdin: false,
244
+ }).start();
197
245
  try {
198
246
  const data = await callHosting(hostingServiceBaseUrl, await getToken(), OPEN_SESSION, {
199
247
  input: {
@@ -203,87 +251,83 @@ export const proxyDatabase = async (args) => {
203
251
  ttlMinutes: args.ttlMinutes,
204
252
  },
205
253
  });
206
- session = data.openDatabaseAccessSession;
254
+ spinner.stop();
255
+ return data.openDatabaseAccessSession;
207
256
  }
208
257
  catch (error) {
209
- writeStatus(red(`Could not open a session for service [${args.serviceId}].`));
258
+ spinner.fail(`Could not open a session for service [${args.serviceId}].`);
210
259
  writeStatus(red(describeError(error)));
211
260
  process.exit(exitCode);
212
261
  }
213
- const closeSession = async () => {
214
- // Fresh: the startup token may have lapsed, and a 401 strands the role.
215
- const token = await getToken();
216
- const data = await callHosting(hostingServiceBaseUrl, token, CLOSE_SESSION, {
262
+ };
263
+ /** Closes the session and reports the outcome. Resolves to the exit code. */
264
+ const closeSession = async (hostingServiceBaseUrl, getToken, session) => {
265
+ try {
266
+ // Fresh token: the startup one may have lapsed, and a 401 strands the role.
267
+ const data = await callHosting(hostingServiceBaseUrl, await getToken(), CLOSE_SESSION, {
217
268
  input: { databaseAccessSessionId: session.databaseAccessSessionId },
218
269
  });
219
- return data.closeDatabaseAccessSession.status;
220
- };
221
- const server = net.createServer((client) => databaseProxyConnection(client, session, getToken));
222
- // Bound before printing: a bind error gives the session back.
223
- try {
224
- await listen(server, port);
225
- }
226
- catch (error) {
227
- writeStatus(red(`Could not listen on ${LOOPBACK}:${port}.`));
228
- writeStatus(red(describeError(error)));
229
- try {
230
- await closeSession();
231
- writeStatus(dim('The session was closed again.'));
270
+ if (data.closeDatabaseAccessSession.status === 'CLOSED') {
271
+ writeStatus(green('Session closed and the database role dropped.'));
232
272
  }
233
- catch (closeError) {
234
- writeStatus(yellow(`The session could not be closed and will expire at ${session.expiresAt}: ${describeError(closeError)}`));
273
+ else {
274
+ // CLOSING: the role outlives the command by at most one reconciliation
275
+ // pass, so there is nothing useful to wait here for.
276
+ writeStatus(yellow('Local proxy closed. Dropping the database role is still pending and will be completed by the service.'));
235
277
  }
236
- process.exit(exitCode);
278
+ return 0;
237
279
  }
238
- let closing = false;
239
- const shutdown = async (signal) => {
240
- if (closing) {
241
- return;
242
- }
243
- closing = true;
244
- writeStatus(dim(`\n${signal} - closing the session...`));
245
- server.close();
246
- try {
247
- const status = await closeSession();
248
- if (status === 'CLOSED') {
249
- writeStatus(green('Session closed and the database role dropped.'));
250
- }
251
- else {
252
- // CLOSING: the role outlives the command by at most one reconciliation
253
- // pass, so there is nothing useful to wait here for.
254
- writeStatus(yellow('Local proxy closed. Dropping the database role is still pending and will be completed by the service.'));
255
- }
256
- process.exit(0);
257
- }
258
- catch (error) {
259
- writeStatus(yellow(`The session could not be closed and will expire at ${session.expiresAt}: ${describeError(error)}`));
260
- process.exit(exitCode);
261
- }
262
- };
263
- // Node exits on all three by default, skipping the close. SIGKILL cannot be
264
- // caught; that falls to the session's expiry.
265
- for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP']) {
266
- process.on(signal, () => void shutdown(signal));
280
+ catch (error) {
281
+ writeStatus(yellow(`The session could not be closed and will expire at ${session.expiresAt}: ${describeError(error)}`));
282
+ return exitCode;
267
283
  }
284
+ };
285
+ const printSession = (args, session, port) => {
268
286
  const clampWarning = formatClampedTtlWarning(args.ttlMinutes, session.expiresAt);
269
287
  if (clampWarning) {
270
288
  writeStatus(yellow(clampWarning));
271
289
  }
272
290
  if (args.json === true) {
273
291
  writeOut(JSON.stringify(toConnectionJson(session, port)));
292
+ return;
274
293
  }
275
- else {
276
- writeStatus(bold(`\nDatabase access to [${args.serviceId}] is open.\n`));
277
- writeOut(formatConnectionDetails(session, port));
278
- writeStatus(dim('\nThe password is shown once and cannot be retrieved again.'));
279
- writeStatus(dim('Press Ctrl+C to close the session.'));
294
+ writeStatus(bold(`\nDatabase access to [${args.serviceId}] is open.\n`));
295
+ writeOut(formatConnectionDetails(session, port));
296
+ writeStatus(dim('\nThe password is shown once and cannot be retrieved again.'));
297
+ writeStatus(dim('Press Ctrl+C to close the session.'));
298
+ };
299
+ const warnBeforeExpiry = (session) => {
300
+ const delay = toExpiryWarningDelay(session.expiresAt);
301
+ if (delay === undefined) {
302
+ return;
280
303
  }
281
- const warningDelay = toExpiryWarningDelay(session.expiresAt);
282
- if (warningDelay !== undefined) {
283
- setTimeout(() => {
284
- writeStatus(yellow(`\nThis session ends at ${session.expiresAt}. Open connections will be dropped.`));
285
- }, warningDelay).unref();
304
+ setTimeout(() => {
305
+ writeStatus(yellow(`\nThis session ends at ${session.expiresAt}. Open connections will be dropped.`));
306
+ }, delay).unref();
307
+ };
308
+ export const proxyDatabase = async (args) => {
309
+ const port = args.localProxyPort ?? DEFAULT_LOCAL_PROXY_PORT;
310
+ const hostingServiceBaseUrl = args.hostingServiceBaseURL;
311
+ const getToken = createTokenProvider(args.idServiceAuthBaseURL, args.mosaicHostingClientId, args.mosaicHostingClientSecret);
312
+ const session = await openSession(args, hostingServiceBaseUrl, getToken);
313
+ const server = net.createServer((client) => databaseProxyConnection(client, session, getToken));
314
+ // Bound before printing: a bind error gives the session back.
315
+ try {
316
+ await listen(server, port);
286
317
  }
318
+ catch (error) {
319
+ writeStatus(red(`Could not listen on ${LOOPBACK}:${port}.`));
320
+ writeStatus(red(describeError(error)));
321
+ await closeSession(hostingServiceBaseUrl, getToken, session);
322
+ process.exit(exitCode);
323
+ }
324
+ onShutdownRequested(() => {
325
+ writeStatus(dim('\nClosing the session...'));
326
+ server.close();
327
+ void closeSession(hostingServiceBaseUrl, getToken, session).then((code) => process.exit(code));
328
+ });
329
+ printSession(args, session, port);
330
+ warnBeforeExpiry(session);
287
331
  };
288
332
  /**
289
333
  * Validate arguments for proxying a direct database connection.
@@ -1 +1 @@
1
- {"version":3,"file":"database-proxy.js","sourceRoot":"","sources":["../../../../../../src/commands/hosting/database/proxy/database-proxy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"database-proxy.js","sourceRoot":"","sources":["../../../../../../src/commands/hosting/database/proxy/database-proxy.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axinom/mosaic-cli",
3
- "version": "0.62.0-rc.4",
3
+ "version": "0.62.0-rc.5",
4
4
  "engines": {
5
5
  "node": ">=20.19.0"
6
6
  },
@@ -55,8 +55,8 @@
55
55
  "@asyncapi/diff": "^0.5.0",
56
56
  "@asyncapi/modelina": "^5.10.1",
57
57
  "@asyncapi/parser": "^3.6.0",
58
- "@axinom/mosaic-id-link-be": "^0.45.0-rc.4",
59
- "@axinom/mosaic-service-common": "^0.75.0-rc.4",
58
+ "@axinom/mosaic-id-link-be": "^0.45.0-rc.5",
59
+ "@axinom/mosaic-service-common": "^0.75.0-rc.5",
60
60
  "@graphql-inspector/core": "3.1.2",
61
61
  "@inquirer/confirm": "^6.1.1",
62
62
  "@inquirer/core": "^11.2.1",
@@ -102,5 +102,5 @@
102
102
  "publishConfig": {
103
103
  "access": "public"
104
104
  },
105
- "gitHead": "c2cd7a254faf3436a01e61dedf194a0c74de9a00"
105
+ "gitHead": "730bc315d301f723ce12ba57c3be2c7e52640a61"
106
106
  }
@@ -3,6 +3,7 @@ import { isNullOrWhitespace } from '@axinom/mosaic-service-common';
3
3
  import axios, { AxiosError, type AxiosInstance } from 'axios';
4
4
  import chalk from 'chalk';
5
5
  import net from 'net';
6
+ import ora from 'ora';
6
7
  import WebSocket, { createWebSocketStream } from 'ws';
7
8
  import { exitCode } from '../../../../common/index.js';
8
9
  import type { DatabaseProxyOptions } from './database-proxy-options.js';
@@ -74,6 +75,9 @@ export const formatClampedTtlWarning = (
74
75
 
75
76
  export const WARN_BEFORE_EXPIRY_MS = 5 * 60_000;
76
77
 
78
+ /** The byte a terminal delivers for Ctrl+C once it stops raising SIGINT. */
79
+ const ETX = 0x03;
80
+
77
81
  /** Undefined when the session is too short for the warning to precede it. */
78
82
  export const toExpiryWarningDelay = (
79
83
  expiresAt: string,
@@ -278,20 +282,66 @@ const listen = (server: net.Server, port: number): Promise<void> =>
278
282
  });
279
283
  });
280
284
 
281
- export const proxyDatabase = async (
282
- args: Required<Pick<DatabaseProxyOptions, 'serviceId'>> &
283
- DatabaseProxyOptions,
284
- ): Promise<void> => {
285
- const port = args.localProxyPort ?? DEFAULT_LOCAL_PROXY_PORT;
286
- const hostingServiceBaseUrl = args.hostingServiceBaseURL as string;
285
+ /** Hands the terminal back; the mode belongs to it, not to this process. */
286
+ const restoreStdinMode = (): void => {
287
+ if (process.stdin.isTTY && process.stdin.isRaw) {
288
+ process.stdin.setRawMode(false);
289
+ process.stdin.pause();
290
+ }
291
+ };
287
292
 
288
- const getToken = createTokenProvider(
289
- args.idServiceAuthBaseURL as string,
290
- args.mosaicHostingClientId as string,
291
- args.mosaicHostingClientSecret as string,
292
- );
293
+ /**
294
+ * Calls `onShutdown` once, on Ctrl+C or a termination signal.
295
+ *
296
+ * Ctrl+C is read from stdin rather than taken as a signal: in raw mode the
297
+ * terminal stops raising one, which keeps it from also killing the `yarn` and
298
+ * `env-cmd` wrappers a solution runs this through. They would exit at once and
299
+ * hand the shell prompt back while the session was still closing.
300
+ */
301
+ const onShutdownRequested = (onShutdown: () => void): void => {
302
+ let requested = false;
303
+ const request = (): void => {
304
+ if (requested) {
305
+ return;
306
+ }
307
+ requested = true;
308
+ onShutdown();
309
+ };
310
+
311
+ process.on('exit', restoreStdinMode);
312
+
313
+ // The baseline everywhere: `kill`, a shutting-down machine, Ctrl+Break, and
314
+ // any stdin that is not a terminal. SIGKILL cannot be caught; that falls to
315
+ // the session's expiry.
316
+ for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP', 'SIGBREAK'] as const) {
317
+ process.on(signal, request);
318
+ }
319
+
320
+ // On a terminal, take the key before it becomes a SIGINT that would kill the
321
+ // wrappers too. Raw mode suppresses that signal on every platform.
322
+ if (process.stdin.isTTY) {
323
+ process.stdin.setRawMode(true);
324
+ process.stdin.resume();
325
+ process.stdin.on('data', (chunk: Buffer) => {
326
+ if (chunk.includes(ETX)) {
327
+ request();
328
+ }
329
+ });
330
+ }
331
+ };
332
+
333
+ const openSession = async (
334
+ args: DatabaseProxyOptions,
335
+ hostingServiceBaseUrl: string,
336
+ getToken: () => Promise<string>,
337
+ ): Promise<DatabaseAccessSession> => {
338
+ // Creating the role is a remote call that regularly takes half a minute.
339
+ const spinner = ora({
340
+ text: `Opening a database access session for [${args.serviceId}]...`,
341
+ // Off: it would put stdin in raw mode, which is this command's to manage.
342
+ discardStdin: false,
343
+ }).start();
293
344
 
294
- let session: DatabaseAccessSession;
295
345
  try {
296
346
  const data = await callHosting<{
297
347
  openDatabaseAccessSession: DatabaseAccessSession;
@@ -303,91 +353,58 @@ export const proxyDatabase = async (
303
353
  ttlMinutes: args.ttlMinutes,
304
354
  },
305
355
  });
306
- session = data.openDatabaseAccessSession;
356
+ spinner.stop();
357
+ return data.openDatabaseAccessSession;
307
358
  } catch (error) {
308
- writeStatus(
309
- red(`Could not open a session for service [${args.serviceId}].`),
310
- );
359
+ spinner.fail(`Could not open a session for service [${args.serviceId}].`);
311
360
  writeStatus(red(describeError(error)));
312
361
  process.exit(exitCode);
313
362
  }
363
+ };
314
364
 
315
- const closeSession = async (): Promise<string> => {
316
- // Fresh: the startup token may have lapsed, and a 401 strands the role.
317
- const token = await getToken();
365
+ /** Closes the session and reports the outcome. Resolves to the exit code. */
366
+ const closeSession = async (
367
+ hostingServiceBaseUrl: string,
368
+ getToken: () => Promise<string>,
369
+ session: DatabaseAccessSession,
370
+ ): Promise<number> => {
371
+ try {
372
+ // Fresh token: the startup one may have lapsed, and a 401 strands the role.
318
373
  const data = await callHosting<{
319
374
  closeDatabaseAccessSession: { status: string };
320
- }>(hostingServiceBaseUrl, token, CLOSE_SESSION, {
375
+ }>(hostingServiceBaseUrl, await getToken(), CLOSE_SESSION, {
321
376
  input: { databaseAccessSessionId: session.databaseAccessSessionId },
322
377
  });
323
- return data.closeDatabaseAccessSession.status;
324
- };
325
-
326
- const server = net.createServer((client) =>
327
- databaseProxyConnection(client, session, getToken),
328
- );
329
-
330
- // Bound before printing: a bind error gives the session back.
331
- try {
332
- await listen(server, port);
333
- } catch (error) {
334
- writeStatus(red(`Could not listen on ${LOOPBACK}:${port}.`));
335
- writeStatus(red(describeError(error)));
336
- try {
337
- await closeSession();
338
- writeStatus(dim('The session was closed again.'));
339
- } catch (closeError) {
340
- writeStatus(
341
- yellow(
342
- `The session could not be closed and will expire at ${
343
- session.expiresAt
344
- }: ${describeError(closeError)}`,
345
- ),
346
- );
347
- }
348
- process.exit(exitCode);
349
- }
350
378
 
351
- let closing = false;
352
- const shutdown = async (signal: string): Promise<void> => {
353
- if (closing) {
354
- return;
355
- }
356
- closing = true;
357
- writeStatus(dim(`\n${signal} - closing the session...`));
358
- server.close();
359
- try {
360
- const status = await closeSession();
361
- if (status === 'CLOSED') {
362
- writeStatus(green('Session closed and the database role dropped.'));
363
- } else {
364
- // CLOSING: the role outlives the command by at most one reconciliation
365
- // pass, so there is nothing useful to wait here for.
366
- writeStatus(
367
- yellow(
368
- 'Local proxy closed. Dropping the database role is still pending and will be completed by the service.',
369
- ),
370
- );
371
- }
372
- process.exit(0);
373
- } catch (error) {
379
+ if (data.closeDatabaseAccessSession.status === 'CLOSED') {
380
+ writeStatus(green('Session closed and the database role dropped.'));
381
+ } else {
382
+ // CLOSING: the role outlives the command by at most one reconciliation
383
+ // pass, so there is nothing useful to wait here for.
374
384
  writeStatus(
375
385
  yellow(
376
- `The session could not be closed and will expire at ${
377
- session.expiresAt
378
- }: ${describeError(error)}`,
386
+ 'Local proxy closed. Dropping the database role is still pending and will be completed by the service.',
379
387
  ),
380
388
  );
381
- process.exit(exitCode);
382
389
  }
383
- };
384
-
385
- // Node exits on all three by default, skipping the close. SIGKILL cannot be
386
- // caught; that falls to the session's expiry.
387
- for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP'] as const) {
388
- process.on(signal, () => void shutdown(signal));
390
+ return 0;
391
+ } catch (error) {
392
+ writeStatus(
393
+ yellow(
394
+ `The session could not be closed and will expire at ${
395
+ session.expiresAt
396
+ }: ${describeError(error)}`,
397
+ ),
398
+ );
399
+ return exitCode;
389
400
  }
401
+ };
390
402
 
403
+ const printSession = (
404
+ args: DatabaseProxyOptions,
405
+ session: DatabaseAccessSession,
406
+ port: number,
407
+ ): void => {
391
408
  const clampWarning = formatClampedTtlWarning(
392
409
  args.ttlMinutes,
393
410
  session.expiresAt,
@@ -398,25 +415,70 @@ export const proxyDatabase = async (
398
415
 
399
416
  if (args.json === true) {
400
417
  writeOut(JSON.stringify(toConnectionJson(session, port)));
401
- } else {
402
- writeStatus(bold(`\nDatabase access to [${args.serviceId}] is open.\n`));
403
- writeOut(formatConnectionDetails(session, port));
418
+ return;
419
+ }
420
+
421
+ writeStatus(bold(`\nDatabase access to [${args.serviceId}] is open.\n`));
422
+ writeOut(formatConnectionDetails(session, port));
423
+ writeStatus(
424
+ dim('\nThe password is shown once and cannot be retrieved again.'),
425
+ );
426
+ writeStatus(dim('Press Ctrl+C to close the session.'));
427
+ };
428
+
429
+ const warnBeforeExpiry = (session: DatabaseAccessSession): void => {
430
+ const delay = toExpiryWarningDelay(session.expiresAt);
431
+ if (delay === undefined) {
432
+ return;
433
+ }
434
+ setTimeout(() => {
404
435
  writeStatus(
405
- dim('\nThe password is shown once and cannot be retrieved again.'),
436
+ yellow(
437
+ `\nThis session ends at ${session.expiresAt}. Open connections will be dropped.`,
438
+ ),
406
439
  );
407
- writeStatus(dim('Press Ctrl+C to close the session.'));
408
- }
440
+ }, delay).unref();
441
+ };
409
442
 
410
- const warningDelay = toExpiryWarningDelay(session.expiresAt);
411
- if (warningDelay !== undefined) {
412
- setTimeout(() => {
413
- writeStatus(
414
- yellow(
415
- `\nThis session ends at ${session.expiresAt}. Open connections will be dropped.`,
416
- ),
417
- );
418
- }, warningDelay).unref();
443
+ export const proxyDatabase = async (
444
+ args: Required<Pick<DatabaseProxyOptions, 'serviceId'>> &
445
+ DatabaseProxyOptions,
446
+ ): Promise<void> => {
447
+ const port = args.localProxyPort ?? DEFAULT_LOCAL_PROXY_PORT;
448
+ const hostingServiceBaseUrl = args.hostingServiceBaseURL as string;
449
+
450
+ const getToken = createTokenProvider(
451
+ args.idServiceAuthBaseURL as string,
452
+ args.mosaicHostingClientId as string,
453
+ args.mosaicHostingClientSecret as string,
454
+ );
455
+
456
+ const session = await openSession(args, hostingServiceBaseUrl, getToken);
457
+
458
+ const server = net.createServer((client) =>
459
+ databaseProxyConnection(client, session, getToken),
460
+ );
461
+
462
+ // Bound before printing: a bind error gives the session back.
463
+ try {
464
+ await listen(server, port);
465
+ } catch (error) {
466
+ writeStatus(red(`Could not listen on ${LOOPBACK}:${port}.`));
467
+ writeStatus(red(describeError(error)));
468
+ await closeSession(hostingServiceBaseUrl, getToken, session);
469
+ process.exit(exitCode);
419
470
  }
471
+
472
+ onShutdownRequested(() => {
473
+ writeStatus(dim('\nClosing the session...'));
474
+ server.close();
475
+ void closeSession(hostingServiceBaseUrl, getToken, session).then((code) =>
476
+ process.exit(code),
477
+ );
478
+ });
479
+
480
+ printSession(args, session, port);
481
+ warnBeforeExpiry(session);
420
482
  };
421
483
 
422
484
  /**