• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

RobinTail / express-zod-api / 4410939844

pending completion
4410939844

Pull #880

github

GitHub
Merge 1f79a241a into 1ca06dc0d
Pull Request #880: Bump @typescript-eslint/eslint-plugin from 5.54.1 to 5.55.0

499 of 524 branches covered (95.23%)

1119 of 1119 relevant lines covered (100.0%)

385.91 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.78
/src/metadata.ts
1
import { combinations } from "./common-helpers";
200✔
2
import { z } from "./index";
3
import { mergeDeepRight } from "ramda";
200✔
4

5
export const metaProp = "expressZodApiMeta";
200✔
6
type MetaProp = typeof metaProp;
7

8
export type MetaDef<T extends z.ZodTypeAny> = {
9
  [K in MetaProp]: {
10
    examples: z.input<T>[];
11
  };
12
};
13
type MetaKey = keyof MetaDef<any>[MetaProp];
14
type MetaValue<T extends z.ZodTypeAny, K extends MetaKey> = Readonly<
15
  MetaDef<T>[MetaProp][K]
16
>;
17

18
type ExampleSetter<T extends z.ZodTypeAny> = (
19
  example: z.input<T>
20
) => WithMeta<T>;
21

22
/**
23
 * @desc fixes the incompatibility of the ZodObject.keyof() method introduced in v3.17.9
24
 * @todo remove it if/when it will be compatible
25
 */
26
type MetaFixForStrippedObject<T> = T extends z.ZodObject<any>
27
  ? T & { keyof: z.ZodObject<any>["keyof"] }
28
  : T;
29

30
type WithMeta<T extends z.ZodTypeAny> = MetaFixForStrippedObject<T> & {
31
  _def: T["_def"] & MetaDef<T>;
32
  example: ExampleSetter<T>;
33
};
34

35
export const withMeta = <T extends z.ZodTypeAny>(schema: T) => {
200✔
36
  const def = schema._def as MetaDef<T>;
1,984✔
37
  def[metaProp] = def[metaProp] || { examples: [] };
1,984✔
38
  if (!("example" in schema)) {
1,984✔
39
    Object.defineProperties(schema, {
1,904✔
40
      example: {
41
        get: (): ExampleSetter<T> => (value) => {
1,248✔
42
          def[metaProp].examples.push(value);
1,232✔
43
          return schema as WithMeta<T>;
1,232✔
44
        },
45
      },
46
    });
47
  }
48
  return schema as WithMeta<T>;
1,984✔
49
};
50

51
export const hasMeta = <T extends z.ZodTypeAny>(
200✔
52
  schema: T
53
): schema is WithMeta<T> => {
54
  if (!(metaProp in schema._def)) {
9,024✔
55
    return false;
6,992✔
56
  }
57
  return (
2,032✔
58
    typeof schema._def[metaProp] === "object" && schema._def[metaProp] !== null
4,048✔
59
  );
60
};
61

62
export function getMeta<T extends z.ZodTypeAny, K extends MetaKey>(
200✔
63
  schema: T,
64
  meta: K
65
): MetaValue<T, K> | undefined {
66
  if (!hasMeta(schema)) {
7,688✔
67
    return undefined;
5,864✔
68
  }
69
  const def = schema._def as MetaDef<T>;
1,824✔
70
  return meta in def[metaProp] ? def[metaProp][meta] : undefined;
1,824!
71
}
72

73
export const copyMeta = <A extends z.ZodTypeAny, B extends z.ZodTypeAny>(
200✔
74
  src: A,
75
  dest: B
76
): B | WithMeta<B> => {
77
  if (!hasMeta(src)) {
1,272✔
78
    return dest;
1,120✔
79
  }
80
  dest = withMeta(dest);
152✔
81
  const def = dest._def as MetaDef<B>;
152✔
82
  const examplesCombinations = combinations(
152✔
83
    def[metaProp].examples,
84
    src._def[metaProp].examples
85
  );
86
  // general deep merge except examples
87
  def[metaProp] = mergeDeepRight(
152✔
88
    { ...def[metaProp], examples: [] },
89
    { ...src._def[metaProp], examples: [] }
90
  );
91
  if (examplesCombinations.type === "single") {
152✔
92
    def[metaProp].examples = examplesCombinations.value;
88✔
93
  } else {
94
    for (const [destExample, srcExample] of examplesCombinations.value) {
64✔
95
      def[metaProp].examples.push(
104✔
96
        mergeDeepRight({ ...destExample }, { ...srcExample })
97
      );
98
    }
99
  }
100
  return dest;
152✔
101
};
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc