-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvalidate.ts
More file actions
142 lines (129 loc) · 4.16 KB
/
Copy pathvalidate.ts
File metadata and controls
142 lines (129 loc) · 4.16 KB
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright 2023-latest the httpland authors. All rights reserved. MIT license.
// This module is browser compatible.
import {
isNonNegativeInteger,
isNumber,
isString,
isUndefined,
} from "./deps.ts";
import type { IntRange, OtherRange, RangeSpec, SuffixRange } from "./types.ts";
/** Whether the {@link RangeSpec} is {@link IntRange} or not.
*
* @example
* ```ts
* import {
* type IntRange,
* isIntRange,
* type OtherRange,
* type SuffixRange,
* } from "https://deno.land/x/range_parser@$VERSION/mod.ts";
* import { assert } from "https://deno.land/std/testing/asserts.ts";
*
* declare const intRange: IntRange;
* declare const suffixRange: SuffixRange;
* declare const otherRange: OtherRange;
*
* assert(isIntRange(intRange));
* assert(!isIntRange(suffixRange));
* assert(!isIntRange(otherRange));
* ```
*/
export function isIntRange(rangeSpec: RangeSpec): rangeSpec is IntRange {
return !isString(rangeSpec) && "firstPos" in rangeSpec;
}
/** Whether the {@link RangeSpec} is {@link SuffixRange} or not.
*
* @example
* ```ts
* import {
* type IntRange,
* isSuffixRange,
* type OtherRange,
* type SuffixRange,
* } from "https://deno.land/x/range_parser@$VERSION/mod.ts";
* import { assert } from "https://deno.land/std/testing/asserts.ts";
*
* declare const intRange: IntRange;
* declare const suffixRange: SuffixRange;
* declare const otherRange: OtherRange;
*
* assert(isSuffixRange(suffixRange));
* assert(!isSuffixRange(intRange));
* assert(!isSuffixRange(otherRange));
* ```
*/
export function isSuffixRange(rangeSpec: RangeSpec): rangeSpec is SuffixRange {
return !isString(rangeSpec) && "suffixLength" in rangeSpec;
}
/** Whether the {@link RangeSpec} is {@link OtherRange} or not.
*
* @example
* ```ts
* import {
* type IntRange,
* isOtherRange,
* type OtherRange,
* type SuffixRange,
* } from "https://deno.land/x/range_parser@$VERSION/mod.ts";
* import { assert } from "https://deno.land/std/testing/asserts.ts";
*
* declare const intRange: IntRange;
* declare const suffixRange: SuffixRange;
* declare const otherRange: OtherRange;
*
* assert(isOtherRange(otherRange));
* assert(!isOtherRange(intRange));
* assert(!isOtherRange(suffixRange));
* ```
*/
export function isOtherRange(rangeSpec: RangeSpec): rangeSpec is OtherRange {
return isString(rangeSpec);
}
/** Whether the {@link IntRange} is valid or not. */
export function isValidIntRange(intRange: IntRange): boolean {
return isNonNegativeInteger(intRange.firstPos) &&
(
isUndefined(intRange.lastPos) ||
(isNumber(intRange.lastPos) &&
isNonNegativeInteger(intRange.lastPos) &&
intRange.firstPos <= intRange.lastPos)
);
}
/** Whether the {@link SuffixRange} is valid or not. */
export function isValidSuffixRange(suffixRange: SuffixRange): boolean {
return isNonNegativeInteger(suffixRange.suffixLength);
}
const ReOtherRange = /^[\x21-\x2B\x2D-\x7E]+$/;
/** Whether the {@link OtherRange} is valid or not. */
export function isValidOtherRange(otherRange: OtherRange): boolean {
return ReOtherRange.test(otherRange);
}
export const RangeSpecifierRe =
/^[\w!#$%&'*+.^`|~-]+=(((\d)+-((\d)+)?)|(-(\d)+)|([\x21-\x2B\x2D-\x7E]+))([\t ]*?,[\t ]*?(((\d)+-((\d)+)?)|(-(\d)+)|([\x21-\x2B\x2D-\x7E]+)))*$/;
/** Whether the input is HTTP `Range` header field format or not.
*
* @example
* ```ts
* import { isRangeFormat } from "https://deno.land/x/range_parser@$VERSION/mod.ts";
* import { assert } from "https://deno.land/std/testing/asserts.ts";
*
* assert(isRangeFormat("bytes=0-100, 200-, -500"));
* assert(!isRangeFormat("<invalid>"));
* ```
*/
export function isRangeFormat(input: string): boolean {
return RangeSpecifierRe.test(input.trim());
}
export const ReRangeUnit = /^[\w!#$%&'*+.^`|~-]+$/;
/** Whether the input is `<range-unit>` format or not. */
export function isRangeUnitFormat(input: string): boolean {
return ReRangeUnit.test(input);
}
/** Assert for `<range-unit>` format.
* @throws {TypeError} If the input is not `<range-unit>` format.
*/
export function assertRangeUnitFormat(input: string): asserts input {
if (!isRangeUnitFormat(input)) {
throw TypeError("invalid <range-unit> format.");
}
}