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

RobinTail / express-zod-api / 11783971106

11 Nov 2024 06:15PM UTC coverage: 100.0%. Remained the same
11783971106

Pull #2164

github

web-flow
Merge 7cb42cc86 into 919f2d494
Pull Request #2164: Bump the typescript-eslint group with 2 updates

1148 of 1168 branches covered (98.29%)

3893 of 3893 relevant lines covered (100.0%)

382.96 hits per line

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

100.0
/src/deep-checks.ts
1
import { fail } from "node:assert/strict";
6✔
2
import { z } from "zod";
3
import { EmptyObject } from "./common-helpers";
4
import { ezDateInBrand } from "./date-in-schema";
5
import { ezDateOutBrand } from "./date-out-schema";
6
import { ezFileBrand } from "./file-schema";
7
import { IOSchema } from "./io-schema";
8
import { metaSymbol } from "./metadata";
9
import { ProprietaryBrand } from "./proprietary-schemas";
10
import { ezRawBrand } from "./raw-schema";
11
import { HandlingRules, NextHandlerInc, SchemaHandler } from "./schema-walker";
12
import { ezUploadBrand } from "./upload-schema";
13

14
/** @desc Check is a schema handling rule returning boolean */
15
type Check = SchemaHandler<boolean>;
16

17
const onSomeUnion: Check = (
6✔
18
  schema:
120✔
19
    | z.ZodUnion<z.ZodUnionOptions>
20
    | z.ZodDiscriminatedUnion<string, z.ZodDiscriminatedUnionOption<string>[]>,
21
  { next },
120✔
22
) => schema.options.some(next);
120✔
23

24
const onIntersection: Check = (
6✔
25
  { _def }: z.ZodIntersection<z.ZodTypeAny, z.ZodTypeAny>,
348✔
26
  { next },
348✔
27
) => [_def.left, _def.right].some(next);
348✔
28

29
const onWrapped: Check = (
6✔
30
  schema:
210✔
31
    | z.ZodOptional<z.ZodTypeAny>
32
    | z.ZodNullable<z.ZodTypeAny>
33
    | z.ZodReadonly<z.ZodTypeAny>
34
    | z.ZodBranded<z.ZodTypeAny, string | number | symbol>,
35
  { next },
210✔
36
) => next(schema.unwrap());
210✔
37

38
const ioChecks: HandlingRules<boolean, EmptyObject, z.ZodFirstPartyTypeKind> = {
6✔
39
  ZodObject: ({ shape }: z.ZodObject<z.ZodRawShape>, { next }) =>
6✔
40
    Object.values(shape).some(next),
3,006✔
41
  ZodUnion: onSomeUnion,
6✔
42
  ZodDiscriminatedUnion: onSomeUnion,
6✔
43
  ZodIntersection: onIntersection,
6✔
44
  ZodEffects: (schema: z.ZodEffects<z.ZodTypeAny>, { next }) =>
6✔
45
    next(schema.innerType()),
276✔
46
  ZodOptional: onWrapped,
6✔
47
  ZodNullable: onWrapped,
6✔
48
  ZodRecord: ({ valueSchema }: z.ZodRecord, { next }) => next(valueSchema),
6✔
49
  ZodArray: ({ element }: z.ZodArray<z.ZodTypeAny>, { next }) => next(element),
6✔
50
  ZodDefault: ({ _def }: z.ZodDefault<z.ZodTypeAny>, { next }) =>
6✔
51
    next(_def.innerType),
30✔
52
};
6✔
53

54
interface NestedSchemaLookupProps {
55
  condition?: (schema: z.ZodTypeAny) => boolean;
56
  rules?: HandlingRules<
57
    boolean,
58
    EmptyObject,
59
    z.ZodFirstPartyTypeKind | ProprietaryBrand
60
  >;
61
  maxDepth?: number;
62
  depth?: number;
63
}
64

65
/** @desc The optimized version of the schema walker for boolean checks */
66
export const hasNestedSchema = (
6✔
67
  subject: z.ZodTypeAny,
7,056✔
68
  {
7,056✔
69
    condition,
7,056✔
70
    rules = ioChecks,
7,056✔
71
    depth = 1,
7,056✔
72
    maxDepth = Number.POSITIVE_INFINITY,
7,056✔
73
  }: NestedSchemaLookupProps,
7,056✔
74
): boolean => {
7,056✔
75
  if (condition?.(subject)) return true;
7,056✔
76
  const handler =
6,936✔
77
    depth < maxDepth
6,936✔
78
      ? rules[subject._def[metaSymbol]?.brand as keyof typeof rules] ||
6,396✔
79
        rules[subject._def.typeName as keyof typeof rules]
6,366✔
80
      : undefined;
540✔
81
  if (handler) {
7,056✔
82
    return handler(subject, {
4,170✔
83
      next: (schema) =>
4,170✔
84
        hasNestedSchema(schema, {
4,632✔
85
          condition,
4,632✔
86
          rules,
4,632✔
87
          maxDepth,
4,632✔
88
          depth: depth + 1,
4,632✔
89
        }),
4,632✔
90
    } as EmptyObject & NextHandlerInc<boolean>);
4,170✔
91
  }
4,170✔
92
  return false;
2,766✔
93
};
2,766✔
94

95
export const hasUpload = (subject: IOSchema) =>
6✔
96
  hasNestedSchema(subject, {
888✔
97
    condition: (schema) => schema._def[metaSymbol]?.brand === ezUploadBrand,
888✔
98
  });
888✔
99

100
export const hasRaw = (subject: IOSchema) =>
6✔
101
  hasNestedSchema(subject, {
864✔
102
    condition: (schema) => schema._def[metaSymbol]?.brand === ezRawBrand,
864✔
103
    maxDepth: 3,
864✔
104
  });
864✔
105

106
/** @throws AssertionError with incompatible schema constructor */
107
export const assertJsonCompatible = (subject: IOSchema, dir: "in" | "out") => {
6✔
108
  const lazies = new WeakSet<z.ZodLazy<z.ZodTypeAny>>();
576✔
109
  return hasNestedSchema(subject, {
576✔
110
    maxDepth: 300,
576✔
111
    rules: {
576✔
112
      ...ioChecks,
576✔
113
      ZodBranded: onWrapped,
576✔
114
      ZodReadonly: onWrapped,
576✔
115
      ZodCatch: ({ _def: { innerType } }: z.ZodCatch<z.ZodTypeAny>, { next }) =>
576✔
116
        next(innerType),
6✔
117
      ZodPipeline: (
576✔
118
        { _def }: z.ZodPipeline<z.ZodTypeAny, z.ZodTypeAny>,
6✔
119
        { next },
6✔
120
      ) => next(_def[dir]),
6✔
121
      ZodLazy: (lazy: z.ZodLazy<z.ZodTypeAny>, { next }) =>
576✔
122
        lazies.has(lazy) ? false : lazies.add(lazy) && next(lazy.schema),
6!
123
      ZodTuple: ({ items, _def: { rest } }: z.AnyZodTuple, { next }) =>
576✔
124
        [...items].concat(rest ?? []).some(next),
12✔
125
      ZodEffects: { out: undefined, in: ioChecks.ZodEffects }[dir],
576✔
126
      ZodNaN: () => fail("z.nan()"),
576✔
127
      ZodSymbol: () => fail("z.symbol()"),
576✔
128
      ZodFunction: () => fail("z.function()"),
576✔
129
      ZodMap: () => fail("z.map()"),
576✔
130
      ZodSet: () => fail("z.set()"),
576✔
131
      ZodBigInt: () => fail("z.bigint()"),
576✔
132
      ZodVoid: () => fail("z.void()"),
576✔
133
      ZodPromise: () => fail("z.promise()"),
576✔
134
      ZodNever: () => fail("z.never()"),
576✔
135
      ZodDate: () => dir === "in" && fail("z.date()"),
576✔
136
      [ezDateOutBrand]: () => dir === "in" && fail("ez.dateOut()"),
576✔
137
      [ezDateInBrand]: () => dir === "out" && fail("ez.dateIn()"),
576✔
138
      [ezRawBrand]: () => dir === "out" && fail("ez.raw()"),
576✔
139
      [ezUploadBrand]: () => dir === "out" && fail("ez.upload()"),
576✔
140
      [ezFileBrand]: () => false,
576✔
141
    },
576✔
142
  });
576✔
143
};
576✔
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

© 2026 Coveralls, Inc