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

plusnew / router / 14168719779

31 Mar 2025 09:44AM UTC coverage: 83.428% (-8.3%) from 91.712%
14168719779

Pull #349

github

web-flow
Merge 9cf30c16d into 0b7c03408
Pull Request #349: 4.0.0 Nested Routes, Default Handling

182 of 232 branches covered (78.45%)

Branch coverage included in aggregate %.

850 of 1005 new or added lines in 12 files covered. (84.58%)

850 of 1005 relevant lines covered (84.58%)

29.55 hits per line

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

83.0
/src/schema/string.ts
1
import { TOKENS, type Tokenizer } from "../tokenizer";
1✔
2
import type { schema } from "../types";
1✔
3

1✔
4
export default function <
6✔
5
  T extends string = string,
6✔
6
  U extends T | null | undefined = undefined,
6✔
7
>(opt?: {
6✔
8
  validate?: (value: string) => value is T;
6✔
9
  default?: U;
6✔
10
}): NoInfer<
6✔
11
  schema<
6✔
12
    T | (null extends U ? null : never),
6✔
13
    T | (U extends T ? null : never) | (U extends null ? null : never)
6✔
14
  >
6✔
15
> {
6✔
16
  return {
6✔
17
    // eslint-disable-next-line require-yield
6✔
18
    fromUrl: function* (tokenizer, hasValues) {
6✔
19
      if (hasValues === false) {
7✔
20
        if (opt?.default !== undefined) {
2✔
21
          return opt.default;
2✔
22
        }
2!
NEW
23
        throw new Error("No default value provided");
×
NEW
24
      }
✔
25
      let result = getText(tokenizer) ?? "";
7!
26

7✔
27
      while (tokenizer.isDone() === false) {
7✔
28
        const more = getText(tokenizer);
7✔
29
        if (more === null) {
7✔
30
          break;
5✔
31
        } else {
7✔
32
          result += more;
2✔
33
        }
2✔
34
      }
7✔
35

5✔
36
      if (opt?.validate && opt.validate(result) === false) {
7!
NEW
37
        throw new Error("Validation failed");
×
NEW
38
      }
✔
39

5✔
40
      return result as any;
5✔
41
    },
7✔
42
    toUrl: function (value: string | null) {
6✔
43
      if (value === null) {
6!
NEW
44
        if (opt?.default === undefined) {
×
NEW
45
          throw new Error("No default value provided");
×
NEW
46
        }
×
NEW
47

×
NEW
48
        if (opt.default === null) {
×
NEW
49
          return null;
×
NEW
50
        }
×
NEW
51
        value = opt.default;
×
NEW
52
      }
×
53

6✔
54
      if (opt?.validate && opt.validate(value) === false) {
6✔
55
        throw new Error("Validation failed");
1✔
56
      }
1✔
57

5✔
58
      return encodeURIComponent(value);
5✔
59
    },
6✔
60
    isEqual: function (value) {
6✔
61
      return value === null || (value as string) === opt?.default;
1✔
62
    },
1✔
63
    default: opt?.default,
6✔
64
  };
6✔
65
}
6✔
66

1✔
67
function getText(tokenizer: Tokenizer) {
12✔
68
  if (tokenizer.lookahead({ type: "TEXT" })) {
12✔
69
    return decodeURIComponent(tokenizer.eat({ type: "TEXT" }).value);
6✔
70
  } else if (tokenizer.lookahead({ type: "PROPERTY_SEPERATOR" })) {
6✔
71
    tokenizer.eat({ type: "PROPERTY_SEPERATOR" });
1✔
72
    return TOKENS.PROPERTY_SEPERATOR;
1✔
73
  }
1✔
74
  return null;
5✔
75
}
5✔
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