aboutsummaryrefslogtreecommitdiff
path: root/scripts/apidocs/utils/value-checks.ts
blob: 2a4ee1a98d1b05cef613200466545d7b678d525b (plain)
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
export function exactlyOne<T>(
  input: ReadonlyArray<T>,
  property: string,
  extraDescription: string = ''
): T {
  if (input.length !== 1) {
    throw new Error(
      `Expected exactly one ${property} element, got ${input.length}. ${extraDescription}`
    );
  }

  return input[0];
}

export function optionalOne<T>(
  input: ReadonlyArray<T>,
  property: string,
  extraDescription: string = ''
): T | undefined {
  if (input.length > 1) {
    throw new Error(
      `Expected one optional ${property} element, got ${input.length}. ${extraDescription}`
    );
  }

  return input[0];
}

export function required<T>(
  input: T | undefined,
  property: string,
  extraDescription: string = ''
): NonNullable<T> {
  if (input == null) {
    throw new Error(
      `Expected a value for ${property}, got undefined. ${extraDescription}`
    );
  }

  return input;
}

export function allRequired<T>(
  input: ReadonlyArray<T | undefined>,
  property: string,
  extraDescription: string = ''
): Array<NonNullable<T>> {
  return input.map((v, i) =>
    required(v, `${property}[${i}]`, extraDescription)
  );
}

export function atLeastOne<T>(
  input: ReadonlyArray<T>,
  property: string,
  extraDescription: string = ''
): ReadonlyArray<T> {
  if (input.length === 0) {
    throw new Error(
      `Expected at least one ${property} element. ${extraDescription}`
    );
  }

  return input;
}

export function atLeastOneAndAllRequired<T>(
  input: ReadonlyArray<T | undefined>,
  property: string,
  extraDescription: string = ''
): ReadonlyArray<NonNullable<T>> {
  return atLeastOne(
    allRequired(input, property, extraDescription),
    property,
    extraDescription
  );
}

export function valueForKey<T>(
  input: Record<string, T>,
  key: string,
  extraDescription: string = ''
): T {
  return required(input[key], key, extraDescription);
}

export function valuesForKeys<T>(
  input: Record<string, T>,
  keys: string[],
  extraDescription: string = ''
): T[] {
  return keys.map((key) => valueForKey(input, key, extraDescription));
}