๐Ÿ“ฆ nestjs / terminus

๐Ÿ“„ health-check.decorator.ts ยท 85 lines
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
85import { Header } from '@nestjs/common';
import { getHealthCheckSchema } from './health-check.schema';

// eslint-disable-next-line @typescript-eslint/consistent-type-imports
type Swagger = typeof import('@nestjs/swagger');

/**
 * @publicApi
 */
export interface HealthCheckOptions {
  /**
   * Whether to cache the response or not.
   * - If set to `true`, the response header will be set to `Cache-Control: no-cache, no-store, must-revalidate`.
   * - If set to `false`, no header will be set and can be set manually with e.g. `@Header('Cache-Control', 'max-age=604800')`.
   *
   * @default true
   */
  noCache?: boolean;
  /**
   * Whether to document the endpoint with Swagger or not.
   *
   * @default true
   */
  swaggerDocumentation?: boolean;
}

/**
 * Marks the endpoint as a Health Check endpoint.
 *
 * - If the `@nestjs/swagger` package is installed, the endpoint will be documented.
 * - Per default, the response will not be cached.
 *
 * @publicApi
 */
export const HealthCheck = (
  { noCache, swaggerDocumentation }: HealthCheckOptions = {
    noCache: true,
    swaggerDocumentation: true,
  },
) => {
  const decorators: MethodDecorator[] = [];

  if (swaggerDocumentation) {
    let swagger: Swagger | null = null;
    try {
      swagger = require('@nestjs/swagger');
    } catch {}

    if (swagger) {
      decorators.push(...getSwaggerDefinitions(swagger));
    }
  }

  if (noCache) {
    const CacheControl = Header(
      'Cache-Control',
      'no-cache, no-store, must-revalidate',
    );

    decorators.push(CacheControl);
  }

  return (target: any, key: any, descriptor: PropertyDescriptor) => {
    decorators.forEach((decorator) => {
      decorator(target, key, descriptor);
    });
  };
};

function getSwaggerDefinitions(swagger: Swagger) {
  const { ApiOkResponse, ApiServiceUnavailableResponse } = swagger;

  const ServiceUnavailable = ApiServiceUnavailableResponse({
    description: 'The Health Check is not successful',
    schema: getHealthCheckSchema('error'),
  });

  const Ok = ApiOkResponse({
    description: 'The Health Check is successful',
    schema: getHealthCheckSchema('ok'),
  });

  return [ServiceUnavailable, Ok];
}