# All files / microservices/client client-nats.ts

95.12% Statements 39/41
87.5% Branches 14/16
90% Functions 9/10
95% Lines 38/40

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    1071x
    1x
    1x
    1x

    1x
    1x

    1x

    1x
    2x

    2x
    2x
    2x

    2x

    1x
    1x
    1x

    9x
    5x

    4x
    4x

    4x

    4x

    5x

    1x

    5x
    3x
    1x

    2x
    2x
    1x

    1x

    3x
    3x
    2x

    2x

    2x

    2x

    1x

     import { Logger } from '@nestjs/common/services/logger.service';
    import { loadPackage } from '@nestjs/common/utils/load-package.util';
    import { share } from 'rxjs/operators';
    import { ERROR_EVENT, NATS_DEFAULT_URL } from '../constants';
    import { Client } from '../external/nats-client.interface';
    import { NatsOptions, PacketId, ReadPacket, WritePacket } from '../interfaces';
    import { ClientOptions } from '../interfaces/client-metadata.interface';
    import { ClientProxy } from './client-proxy';
    import { CONN_ERR } from './constants';

    let natsPackage: any = {};

    export class ClientNats extends ClientProxy {
      protected readonly logger = new Logger(ClientProxy.name);
      protected readonly url: string;
      protected natsClient: Client;
      protected connection: Promise<any>;

      constructor(protected readonly options: ClientOptions['options']) {
        super();
        this.url =
          this.getOptionsProp<NatsOptions>(this.options, 'url') || NATS_DEFAULT_URL;
        natsPackage = loadPackage('nats', ClientNats.name);
      }

      public close() {
        this.natsClient && this.natsClient.close();
        this.natsClient = null;
        this.connection = null;
      }

      public async connect(): Promise<any> {
        if (this.natsClient) {
          return this.connection;
        }
        this.natsClient = this.createClient();
        this.handleError(this.natsClient);

        this.connection = await this.connect$(this.natsClient)
          .pipe(share())
          .toPromise();
        return this.connection;
      }

      public createClient(): Client {
        const options: any = this.options || ({} as NatsOptions);
        return natsPackage.connect({
          ...options,
          url: this.url,
          json: true,
        });
      }

      public handleError(client: Client) {
        client.addListener(
          ERROR_EVENT,
          err => err.code !== CONN_ERR && this.logger.error(err),
        );
      }

      public createSubscriptionHandler(
        packet: ReadPacket & PacketId,
        callback: (packet: WritePacket) => any,
      ): Function {
        return (message: WritePacket & PacketId) => {
          if (message.id !== packet.id) {
            return undefined;
          }
          const { err, response, isDisposed } = message;
          if (isDisposed || err) {
            return callback({
              err,
              response: null,
              isDisposed: true,
            });
          }
          callback({
            err,
            response,
          });
        };
      }

      protected publish(
        partialPacket: ReadPacket,
        callback: (packet: WritePacket) => any,
      ): Function {
        try {
          const packet = this.assignPacketId(partialPacket);
          const channel = this.normalizePattern(partialPacket.pattern);

          const subscriptionHandler = this.createSubscriptionHandler(
            packet,
            callback,
          );
          const subscriptionId = this.natsClient.request(
            channel,
            packet as any,
            subscriptionHandler,
          );
          return () => this.natsClient.unsubscribe(subscriptionId);
        } catch (err) {
          callback({ err });
        }
      }
    }