File size: 1,220 Bytes
aa3bec5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import { ApiPropertyOptional } from '@nestjs/swagger';
import type { ApiPropertyOptions } from '@nestjs/swagger';

/**
 * OpenAPI schema for TypeScript string enums.
 * Passing `enum: MyEnum` into @ApiQuery / @ApiPropertyOptional breaks @nestjs/swagger when
 * reflected `type` stays as the enum object (merged metadata), which is mistaken for an object schema.
 */
export function stringEnumSchema<T extends Record<string, string>>(enumeration: T) {
  return {
    type: 'string' as const,
    enum: Object.values(enumeration),
  };
}

type StringEnumRecord = Record<string, string>;

/**
 * @ApiPropertyOptional with `schema` (some @nestjs/swagger typings omit `schema`; cast once here).
 */
export function ApiPropertyStringEnumOptional(
  options: Omit<ApiPropertyOptions, 'enum' | 'type'> & {
    enumObject: StringEnumRecord;
  },
): PropertyDecorator {
  const { enumObject, ...rest } = options;
  // `type: String` overrides reflected TS enum metadata; otherwise @nestjs/swagger treats the enum
  // object as an OpenAPI object schema and fails on keys like LOGIN, ACTIVE, etc.
  return ApiPropertyOptional({
    ...rest,
    type: String,
    schema: stringEnumSchema(enumObject),
  } as ApiPropertyOptions);
}