fix: tighten route integer parsing and test coverage
This commit is contained in:
@@ -11,59 +11,60 @@ import {
|
||||
* Search eBay for listings (default: Buy It Now only, Canada only)
|
||||
*/
|
||||
export async function ebayRoute(req: Request): Promise<Response> {
|
||||
const reqUrl = new URL(req.url);
|
||||
|
||||
const SEARCH_QUERY = getRequiredSearchQuery(req);
|
||||
if (SEARCH_QUERY instanceof Response) {
|
||||
return SEARCH_QUERY;
|
||||
}
|
||||
|
||||
const minPrice = parseNonNegativeIntegerParam(
|
||||
reqUrl.searchParams,
|
||||
"minPrice",
|
||||
);
|
||||
if (minPrice instanceof Response) {
|
||||
return minPrice;
|
||||
}
|
||||
const maxPrice = parseNonNegativeIntegerParam(
|
||||
reqUrl.searchParams,
|
||||
"maxPrice",
|
||||
);
|
||||
if (maxPrice instanceof Response) {
|
||||
return maxPrice;
|
||||
}
|
||||
const strictMode = reqUrl.searchParams.get("strictMode") === "true";
|
||||
const buyItNowOnly = reqUrl.searchParams.get("buyItNowOnly") !== "false";
|
||||
const canadaOnly = reqUrl.searchParams.get("canadaOnly") !== "false";
|
||||
const exclusionsParam = reqUrl.searchParams.get("exclusions");
|
||||
const exclusions = exclusionsParam
|
||||
? exclusionsParam.split(",").map((s) => s.trim())
|
||||
: [];
|
||||
const keywordsParam = reqUrl.searchParams.get("keywords");
|
||||
const keywords = keywordsParam
|
||||
? keywordsParam.split(",").map((s) => s.trim())
|
||||
: [SEARCH_QUERY];
|
||||
|
||||
const maxItems = parseNonNegativeIntegerParam(
|
||||
reqUrl.searchParams,
|
||||
"maxItems",
|
||||
);
|
||||
if (maxItems instanceof Response) {
|
||||
return maxItems;
|
||||
}
|
||||
const hideUnstableResults =
|
||||
reqUrl.searchParams.get("unstableFilter") === "true";
|
||||
const opts = {
|
||||
minPrice,
|
||||
maxPrice,
|
||||
strictMode,
|
||||
exclusions,
|
||||
keywords,
|
||||
buyItNowOnly,
|
||||
canadaOnly,
|
||||
maxItems,
|
||||
};
|
||||
|
||||
try {
|
||||
const reqUrl = new URL(req.url);
|
||||
|
||||
const SEARCH_QUERY = getRequiredSearchQuery(req);
|
||||
if (SEARCH_QUERY instanceof Response) {
|
||||
return SEARCH_QUERY;
|
||||
}
|
||||
|
||||
const minPrice = parseNonNegativeIntegerParam(
|
||||
reqUrl.searchParams,
|
||||
"minPrice",
|
||||
);
|
||||
if (minPrice instanceof Response) {
|
||||
return minPrice;
|
||||
}
|
||||
const maxPrice = parseNonNegativeIntegerParam(
|
||||
reqUrl.searchParams,
|
||||
"maxPrice",
|
||||
);
|
||||
if (maxPrice instanceof Response) {
|
||||
return maxPrice;
|
||||
}
|
||||
const strictMode = reqUrl.searchParams.get("strictMode") === "true";
|
||||
const buyItNowOnly = reqUrl.searchParams.get("buyItNowOnly") !== "false";
|
||||
const canadaOnly = reqUrl.searchParams.get("canadaOnly") !== "false";
|
||||
const exclusionsParam = reqUrl.searchParams.get("exclusions");
|
||||
const exclusions = exclusionsParam
|
||||
? exclusionsParam.split(",").map((s) => s.trim())
|
||||
: [];
|
||||
const keywordsParam = reqUrl.searchParams.get("keywords");
|
||||
const keywords = keywordsParam
|
||||
? keywordsParam.split(",").map((s) => s.trim())
|
||||
: [SEARCH_QUERY];
|
||||
|
||||
const maxItems = parseNonNegativeIntegerParam(
|
||||
reqUrl.searchParams,
|
||||
"maxItems",
|
||||
);
|
||||
if (maxItems instanceof Response) {
|
||||
return maxItems;
|
||||
}
|
||||
const hideUnstableResults =
|
||||
reqUrl.searchParams.get("unstableFilter") === "true";
|
||||
const opts = {
|
||||
minPrice,
|
||||
maxPrice,
|
||||
strictMode,
|
||||
exclusions,
|
||||
keywords,
|
||||
buyItNowOnly,
|
||||
canadaOnly,
|
||||
maxItems,
|
||||
};
|
||||
if (hideUnstableResults) {
|
||||
const items = await fetchEbayItems(SEARCH_QUERY, 1, opts, {
|
||||
hideUnstableResults: true,
|
||||
|
||||
@@ -12,6 +12,15 @@ export function getRequiredSearchQuery(req: Request): string | Response {
|
||||
return query;
|
||||
}
|
||||
|
||||
export function parseNonNegativeIntegerParam(
|
||||
searchParams: URLSearchParams,
|
||||
name: string,
|
||||
defaultValue: number,
|
||||
): number | Response;
|
||||
export function parseNonNegativeIntegerParam(
|
||||
searchParams: URLSearchParams,
|
||||
name: string,
|
||||
): number | undefined | Response;
|
||||
export function parseNonNegativeIntegerParam(
|
||||
searchParams: URLSearchParams,
|
||||
name: string,
|
||||
@@ -21,8 +30,14 @@ export function parseNonNegativeIntegerParam(
|
||||
if (rawValue === null) {
|
||||
return defaultValue;
|
||||
}
|
||||
if (!/^\d+$/.test(rawValue)) {
|
||||
return Response.json(
|
||||
{ message: `Invalid ${name} parameter` },
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
const value = Number(rawValue);
|
||||
if (!Number.isInteger(value) || value < 0) {
|
||||
if (value < 0) {
|
||||
return Response.json(
|
||||
{ message: `Invalid ${name} parameter` },
|
||||
{ status: 400 },
|
||||
|
||||
Reference in New Issue
Block a user