Skip to content

Commit

Permalink
feat: url parse add parseQueryInts function and tests (#81)
Browse files Browse the repository at this point in the history
* feat: add parseQueryInts function and corresponding tests

- Introduced parseQueryInts function to convert URL query parameter values into an array of integers, with support for custom separators.
- Enhanced error handling to throw TypeError for invalid inputs, ensuring robust type safety.
- Added unit tests for parseQueryInts in url-parse.test.ts, covering various input scenarios including valid integers, empty strings, and invalid formats.
- Updated documentation with detailed JSDoc comments in both English and Chinese, clarifying parameters, return values, and error handling.

* feat: add parseQueryNumbers function and corresponding tests

- Introduced parseQueryNumbers function to convert URL query parameter values into an array of numbers, supporting custom separators.
- Enhanced error handling to throw TypeError for invalid inputs, including NaN and Infinity values.
- Added unit tests for parseQueryNumbers in url-parse.test.ts, covering various input scenarios including valid numbers, empty strings, and invalid formats.
- Updated documentation with detailed JSDoc comments in both English and Chinese, clarifying parameters, return values, and error handling.

* chore: update version to 0.2.1 in deno.json
  • Loading branch information
iugo authored Dec 18, 2024
1 parent 18d2f75 commit 93aff67
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 1 deletion.
2 changes: 1 addition & 1 deletion deno.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zsqk/somefn",
"version": "0.2.0",
"version": "0.2.1",
"exports": {
"./js/aes": "./js/aes.ts",
"./js/hash": "./js/hash.ts",
Expand Down
44 changes: 44 additions & 0 deletions js/url-parse.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { assertEquals, assertThrows } from '@std/assert';
import {
parseQueryInt,
parseQueryInts,
parseQueryNumber,
parseQueryNumbers,
parseQueryPositiveInt,
parseQueryPositiveInts,
parseQueryString,
Expand Down Expand Up @@ -144,3 +146,45 @@ Deno.test('parseQueryPositiveInts', () => {
TypeError,
);
});

Deno.test('parseQueryInts', () => {
const url = new URL('https://example.com/path');
url.searchParams.set('a', '1,2,3');
url.searchParams.set('b', '-1,0,1');
url.searchParams.set('c', '');
url.searchParams.set('d', '1|2|3');
url.searchParams.set('e', '1,abc,3');
url.searchParams.set('f', '1.5,2,3');

assertEquals(parseQueryInts(url.searchParams.get('a')), [1, 2, 3]);
assertEquals(parseQueryInts(url.searchParams.get('b')), [-1, 0, 1]);
assertEquals(parseQueryInts(url.searchParams.get('c')), undefined);
assertEquals(
parseQueryInts(url.searchParams.get('d'), { separator: '|' }),
[1, 2, 3],
);
assertThrows(() => parseQueryInts(url.searchParams.get('e')), TypeError);
assertThrows(() => parseQueryInts(url.searchParams.get('f')), TypeError);
});

Deno.test('parseQueryNumbers', () => {
const url = new URL('https://example.com/path');
url.searchParams.set('a', '1,2,3');
url.searchParams.set('b', '-1.5,0,1.5');
url.searchParams.set('c', '');
url.searchParams.set('d', '1|2|3');
url.searchParams.set('e', '1,abc,3');
url.searchParams.set('f', '1,Infinity,3');
url.searchParams.set('g', '1,NaN,3');

assertEquals(parseQueryNumbers(url.searchParams.get('a')), [1, 2, 3]);
assertEquals(parseQueryNumbers(url.searchParams.get('b')), [-1.5, 0, 1.5]);
assertEquals(parseQueryNumbers(url.searchParams.get('c')), undefined);
assertEquals(
parseQueryNumbers(url.searchParams.get('d'), { separator: '|' }),
[1, 2, 3],
);
assertThrows(() => parseQueryNumbers(url.searchParams.get('e')), TypeError);
assertThrows(() => parseQueryNumbers(url.searchParams.get('f')), TypeError);
assertThrows(() => parseQueryNumbers(url.searchParams.get('g')), TypeError);
});
92 changes: 92 additions & 0 deletions js/url-parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,95 @@ export function parseQueryPositiveInts(
throw new TypeError(`invalid query positive int array: ${query}`);
}
}

/**
* Convert URL query parameter value to array of integers
* 将 URL 查询参数值转换为整数数组
*
* @param query - URL query parameter value (typically from url.searchParams.get())
* URL 查询参数值(通常来自 url.searchParams.get())
* @param options - Configuration options
* 配置选项
* @param options.separator - Delimiter used to split the string (默认为逗号 ',')
* 用于分割字符串的分隔符
* @returns An array of integers or undefined
* 返回整数数组或 undefined
* - Returns undefined if input is null, "undefined" or empty string
* 当输入为 null、"undefined" 或空字符串时返回 undefined
* - Returns array of integers for valid input
* 对于有效的数字输入返回整数数组
* - Throws TypeError for invalid input
* 当输入无效时抛出 TypeError
*
* @example
* parseQueryInts('1,2,3') // returns [1, 2, 3]
* parseQueryInts('-1,0,1') // returns [-1, 0, 1]
* parseQueryInts('') // returns undefined
* parseQueryInts('1|2|3', { separator: '|' }) // returns [1, 2, 3]
* parseQueryInts('abc') // throws TypeError
*
* @author iugo <[email protected]>
*/
export function parseQueryInts(
query: string | null,
{ separator = ',' }: { separator?: string } = {},
): number[] | undefined {
if (query === null || query === 'undefined' || query === '') {
return undefined;
}
try {
const arr = query.split(separator).map(toInt);
return arr.length === 0 ? undefined : arr;
} catch (_err) {
throw new TypeError(`invalid query int array: ${query}`);
}
}

/**
* Convert URL query parameter value to array of numbers
* 将 URL 查询参数值转换为数字数组
*
* @param query - URL query parameter value (typically from url.searchParams.get())
* URL 查询参数值(通常来自 url.searchParams.get())
* @param options - Configuration options
* 配置选项
* @param options.separator - Delimiter used to split the string (默认为逗号 ',')
* 用于分割字符串的分隔符
* @returns An array of numbers or undefined
* 返回数字数组或 undefined
* - Returns undefined if input is null, "undefined" or empty string
* 当输入为 null、"undefined" 或空字符串时返回 undefined
* - Returns array of numbers for valid input (包括整数和浮点数)
* 对于有效的数字输入返回数字数组(包括整数和浮点数)
* - Throws TypeError for invalid input or NaN/Infinity values
* 当输入无效或为 NaN/Infinity 时抛出 TypeError
*
* @example
* parseQueryNumbers('1,2,3') // returns [1, 2, 3]
* parseQueryNumbers('-1.5,0,1.5') // returns [-1.5, 0, 1.5]
* parseQueryNumbers('') // returns undefined
* parseQueryNumbers('1|2|3', { separator: '|' }) // returns [1, 2, 3]
* parseQueryNumbers('abc') // throws TypeError
*
* @author iugo <[email protected]>
*/
export function parseQueryNumbers(
query: string | null,
{ separator = ',' }: { separator?: string } = {},
): number[] | undefined {
if (query === null || query === 'undefined' || query === '') {
return undefined;
}
try {
const arr = query.split(separator).map((v) => {
const num = parseQueryNumber(v);
if (num === undefined) {
throw new TypeError(`invalid number: ${v}`);
}
return num;
});
return arr.length === 0 ? undefined : arr;
} catch (_err) {
throw new TypeError(`invalid query number array: ${query}`);
}
}

0 comments on commit 93aff67

Please sign in to comment.