Skip to content

Commit 175289e

Browse files
committed
Add extractNextParameters util
1 parent 55b35b8 commit 175289e

3 files changed

Lines changed: 73 additions & 1 deletion

File tree

src/types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ export type BaseResponse<P = Record<string | number | symbol, never>> = {
5252
search_parameters:
5353
& { engine: string }
5454
& Omit<BaseParameters & P, "api_key" | "no_cache" | "async" | "timeout">;
55+
serpapi_pagination?: { next: string };
56+
pagination?: { next: string };
5557
// deno-lint-ignore no-explicit-any
5658
[key: string]: any; // TODO(seb): use recursive type
5759
};

src/utils.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { EngineMap } from "./engines/engine_map.ts";
12
import { version } from "../version.ts";
23

34
type UrlParameters = Record<
@@ -34,6 +35,30 @@ function getBaseUrl() {
3435
return "https://serpapi.com";
3536
}
3637

38+
type NextParametersKeys<E extends keyof EngineMap> = Omit<
39+
EngineMap[E]["parameters"],
40+
"api_key" | "no_cache" | "async" | "timeout"
41+
>;
42+
type NextParameters<E extends keyof EngineMap> = {
43+
[K in keyof NextParametersKeys<E>]: string;
44+
};
45+
export function extractNextParameters<
46+
E extends keyof EngineMap,
47+
>(json: {
48+
serpapi_pagination?: { next: string };
49+
pagination?: { next: string };
50+
}) {
51+
const nextUrlString = json["serpapi_pagination"]?.["next"] ||
52+
json["pagination"]?.["next"];
53+
54+
if (nextUrlString) {
55+
const nextUrl = new URL(nextUrlString);
56+
const nextParameters = Object.fromEntries(nextUrl.searchParams.entries());
57+
delete nextParameters["engine"];
58+
return nextParameters as NextParameters<E>;
59+
}
60+
}
61+
3762
function getSource() {
3863
const moduleSource = `serpapi@${version}`;
3964
try {

tests/utils_test.ts

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,58 @@ import {
1616
assertMatch,
1717
assertRejects,
1818
} from "https://deno.land/std@0.170.0/testing/asserts.ts";
19-
import { _internals, buildUrl, execute } from "../src/utils.ts";
19+
import {
20+
_internals,
21+
buildUrl,
22+
execute,
23+
extractNextParameters,
24+
} from "../src/utils.ts";
2025

2126
loadSync({ export: true });
2227
const BASE_URL = Deno.env.get("ENV_TYPE") === "local"
2328
? "http://localhost:3000"
2429
: "https://serpapi.com";
2530

31+
describe("extractNextParameters", () => {
32+
it("with serpapi_pagination property", () => {
33+
assertEquals(
34+
extractNextParameters<"google">({
35+
serpapi_pagination: {
36+
next:
37+
"https://serpapi.com/search.json?device=desktop&engine=google&gl=us&google_domain=google.com&hl=en&location=Austin%2C+Texas%2C+United+States&q=coffee&start=10",
38+
},
39+
}),
40+
{
41+
device: "desktop",
42+
gl: "us",
43+
google_domain: "google.com",
44+
hl: "en",
45+
location: "Austin, Texas, United States",
46+
q: "coffee",
47+
start: "10",
48+
},
49+
);
50+
});
51+
52+
it("with pagination property", () => {
53+
assertEquals(
54+
extractNextParameters<"google_scholar_profiles">(
55+
{
56+
pagination: {
57+
next:
58+
"https://serpapi.com/search.json?after_author=rZlDAYoq__8J&engine=google_scholar_profiles&hl=en&mauthors=Mike",
59+
},
60+
},
61+
),
62+
{
63+
after_author: "rZlDAYoq__8J",
64+
hl: "en",
65+
mauthors: "Mike",
66+
},
67+
);
68+
});
69+
});
70+
2671
describe("buildUrl", () => {
2772
let urlStub: Stub;
2873

0 commit comments

Comments
 (0)