Skip to content

Commit 5c7dbcb

Browse files
committed
Convert validation functions to use options pattern with backward compatibility
- Change throws parameter to options: { throws } - Support both legacy boolean and new options object - Add backward compatibility comments - Functions updated: validateName, validateNamespace, validateQualifierKey, validateQualifiers, validateSubpath, validateType, validateVersion, validateRequired, validateRequiredByType, validateStartsWithoutNumber, validateStrings, validateEmptyByType
1 parent f07c6d5 commit 5c7dbcb

File tree

1 file changed

+85
-33
lines changed

1 file changed

+85
-33
lines changed

src/validate.ts

Lines changed: 85 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@ function validateEmptyByType(
2121
type: string,
2222
name: string,
2323
value: unknown,
24-
throws: boolean,
24+
options?: { throws?: boolean } | boolean,
2525
): boolean {
26+
// Support both legacy boolean parameter and new options object for backward compatibility.
27+
const { throws = false } =
28+
typeof options === 'boolean' ? { throws: options } : (options ?? {})
2629
if (!isNullishOrEmptyString(value)) {
2730
if (throws) {
2831
throw new PurlError(`${type} "${name}" component must be empty`)
@@ -34,30 +37,45 @@ function validateEmptyByType(
3437

3538
/**
3639
* Validate package name component.
37-
* @throws {PurlError} When validation fails and throws is true.
40+
* @throws {PurlError} When validation fails and options.throws is true.
3841
*/
39-
function validateName(name: unknown, throws: boolean): boolean {
42+
function validateName(
43+
name: unknown,
44+
options?: { throws?: boolean } | boolean,
45+
): boolean {
46+
// Support both legacy boolean parameter and new options object for backward compatibility.
47+
const opts = typeof options === 'boolean' ? { throws: options } : options
4048
return (
41-
validateRequired('name', name, throws) &&
42-
validateStrings('name', name, throws)
49+
validateRequired('name', name, opts) && validateStrings('name', name, opts)
4350
)
4451
}
4552

4653
/**
4754
* Validate package namespace component.
48-
* @throws {PurlError} When validation fails and throws is true.
55+
* @throws {PurlError} When validation fails and options.throws is true.
4956
*/
50-
function validateNamespace(namespace: unknown, throws: boolean): boolean {
51-
return validateStrings('namespace', namespace, throws)
57+
function validateNamespace(
58+
namespace: unknown,
59+
options?: { throws?: boolean } | boolean,
60+
): boolean {
61+
// Support both legacy boolean parameter and new options object for backward compatibility.
62+
const opts = typeof options === 'boolean' ? { throws: options } : options
63+
return validateStrings('namespace', namespace, opts)
5264
}
5365

5466
/**
5567
* Validate qualifier key format and characters.
56-
* @throws {PurlError} When validation fails and throws is true.
68+
* @throws {PurlError} When validation fails and options.throws is true.
5769
*/
58-
function validateQualifierKey(key: string, throws: boolean): boolean {
70+
function validateQualifierKey(
71+
key: string,
72+
options?: { throws?: boolean } | boolean,
73+
): boolean {
74+
// Support both legacy boolean parameter and new options object for backward compatibility.
75+
const opts = typeof options === 'boolean' ? { throws: options } : options
76+
const { throws = false } = opts ?? {}
5977
// A key cannot start with a number.
60-
if (!validateStartsWithoutNumber('qualifier', key, throws)) {
78+
if (!validateStartsWithoutNumber('qualifier', key, opts)) {
6179
return false
6280
}
6381
// The key must be composed only of ASCII letters and numbers,
@@ -94,9 +112,15 @@ function validateQualifierKey(key: string, throws: boolean): boolean {
94112

95113
/**
96114
* Validate qualifiers object structure and keys.
97-
* @throws {PurlError} When validation fails and throws is true.
115+
* @throws {PurlError} When validation fails and options.throws is true.
98116
*/
99-
function validateQualifiers(qualifiers: unknown, throws: boolean): boolean {
117+
function validateQualifiers(
118+
qualifiers: unknown,
119+
options?: { throws?: boolean } | boolean,
120+
): boolean {
121+
// Support both legacy boolean parameter and new options object for backward compatibility.
122+
const opts = typeof options === 'boolean' ? { throws: options } : options
123+
const { throws = false } = opts ?? {}
100124
if (qualifiers === null || qualifiers === undefined) {
101125
return true
102126
}
@@ -115,7 +139,7 @@ function validateQualifiers(qualifiers: unknown, throws: boolean): boolean {
115139
: (Object.keys(qualifiers as QualifiersObject) as Iterable<string>)
116140
// Use for-of to work with URLSearchParams#keys iterators.
117141
for (const key of keysIterable) {
118-
if (!validateQualifierKey(key, throws)) {
142+
if (!validateQualifierKey(key, opts)) {
119143
return false
120144
}
121145
}
@@ -124,13 +148,16 @@ function validateQualifiers(qualifiers: unknown, throws: boolean): boolean {
124148

125149
/**
126150
* Validate that component is present and not empty.
127-
* @throws {PurlError} When validation fails and throws is true.
151+
* @throws {PurlError} When validation fails and options.throws is true.
128152
*/
129153
function validateRequired(
130154
name: string,
131155
value: unknown,
132-
throws: boolean,
156+
options?: { throws?: boolean } | boolean,
133157
): boolean {
158+
// Support both legacy boolean parameter and new options object for backward compatibility.
159+
const { throws = false } =
160+
typeof options === 'boolean' ? { throws: options } : (options ?? {})
134161
if (isNullishOrEmptyString(value)) {
135162
if (throws) {
136163
throw new PurlError(`"${name}" is a required component`)
@@ -142,14 +169,17 @@ function validateRequired(
142169

143170
/**
144171
* Validate that component is required for specific package type.
145-
* @throws {PurlError} When validation fails and throws is true.
172+
* @throws {PurlError} When validation fails and options.throws is true.
146173
*/
147174
function validateRequiredByType(
148175
type: string,
149176
name: string,
150177
value: unknown,
151-
throws: boolean,
178+
options?: { throws?: boolean } | boolean,
152179
): boolean {
180+
// Support both legacy boolean parameter and new options object for backward compatibility.
181+
const { throws = false } =
182+
typeof options === 'boolean' ? { throws: options } : (options ?? {})
153183
if (isNullishOrEmptyString(value)) {
154184
if (throws) {
155185
throw new PurlError(`${type} requires a "${name}" component`)
@@ -161,13 +191,16 @@ function validateRequiredByType(
161191

162192
/**
163193
* Validate that value does not start with a number.
164-
* @throws {PurlError} When validation fails and throws is true.
194+
* @throws {PurlError} When validation fails and options.throws is true.
165195
*/
166196
function validateStartsWithoutNumber(
167197
name: string,
168198
value: string,
169-
throws: boolean,
199+
options?: { throws?: boolean } | boolean,
170200
): boolean {
201+
// Support both legacy boolean parameter and new options object for backward compatibility.
202+
const { throws = false } =
203+
typeof options === 'boolean' ? { throws: options } : (options ?? {})
171204
if (isNonEmptyString(value)) {
172205
const code = value.charCodeAt(0)
173206
if (code >= 48 /*'0'*/ && code <= 57 /*'9'*/) {
@@ -182,13 +215,16 @@ function validateStartsWithoutNumber(
182215

183216
/**
184217
* Validate that value is a string type.
185-
* @throws {PurlError} When validation fails and throws is true.
218+
* @throws {PurlError} When validation fails and options.throws is true.
186219
*/
187220
function validateStrings(
188221
name: string,
189222
value: unknown,
190-
throws: boolean,
223+
options?: { throws?: boolean } | boolean,
191224
): boolean {
225+
// Support both legacy boolean parameter and new options object for backward compatibility.
226+
const { throws = false } =
227+
typeof options === 'boolean' ? { throws: options } : (options ?? {})
192228
if (value === null || value === undefined || typeof value === 'string') {
193229
return true
194230
}
@@ -200,22 +236,33 @@ function validateStrings(
200236

201237
/**
202238
* Validate subpath component.
203-
* @throws {PurlError} When validation fails and throws is true.
239+
* @throws {PurlError} When validation fails and options.throws is true.
204240
*/
205-
function validateSubpath(subpath: unknown, throws: boolean): boolean {
206-
return validateStrings('subpath', subpath, throws)
241+
function validateSubpath(
242+
subpath: unknown,
243+
options?: { throws?: boolean } | boolean,
244+
): boolean {
245+
// Support both legacy boolean parameter and new options object for backward compatibility.
246+
const opts = typeof options === 'boolean' ? { throws: options } : options
247+
return validateStrings('subpath', subpath, opts)
207248
}
208249

209250
/**
210251
* Validate package type component format and characters.
211-
* @throws {PurlError} When validation fails and throws is true.
252+
* @throws {PurlError} When validation fails and options.throws is true.
212253
*/
213-
function validateType(type: unknown, throws: boolean): boolean {
254+
function validateType(
255+
type: unknown,
256+
options?: { throws?: boolean } | boolean,
257+
): boolean {
258+
// Support both legacy boolean parameter and new options object for backward compatibility.
259+
const opts = typeof options === 'boolean' ? { throws: options } : options
260+
const { throws = false } = opts ?? {}
214261
// The type cannot be nullish, an empty string, or start with a number.
215262
if (
216-
!validateRequired('type', type, throws) ||
217-
!validateStrings('type', type, throws) ||
218-
!validateStartsWithoutNumber('type', type as string, throws)
263+
!validateRequired('type', type, opts) ||
264+
!validateStrings('type', type, opts) ||
265+
!validateStartsWithoutNumber('type', type as string, opts)
219266
) {
220267
return false
221268
}
@@ -252,10 +299,15 @@ function validateType(type: unknown, throws: boolean): boolean {
252299

253300
/**
254301
* Validate package version component.
255-
* @throws {PurlError} When validation fails and throws is true.
302+
* @throws {PurlError} When validation fails and options.throws is true.
256303
*/
257-
function validateVersion(version: unknown, throws: boolean): boolean {
258-
return validateStrings('version', version, throws)
304+
function validateVersion(
305+
version: unknown,
306+
options?: { throws?: boolean } | boolean,
307+
): boolean {
308+
// Support both legacy boolean parameter and new options object for backward compatibility.
309+
const opts = typeof options === 'boolean' ? { throws: options } : options
310+
return validateStrings('version', version, opts)
259311
}
260312

261313
export {

0 commit comments

Comments
 (0)