From 97a59e73ef91cf18b3b1695a27b658780bd5ed48 Mon Sep 17 00:00:00 2001 From: Kiko Beats Date: Sun, 20 Sep 2026 19:06:38 +0200 Subject: [PATCH 1/2] feat(core): export function Page types Editor completions cannot resolve puppeteer-core, so Page and HTTPResponse live in microlink.io itself. Co-authored-by: Cursor --- packages/core/package.json | 1 - packages/core/src/index.d.ts | 69 +++++++++++++++++++++++++++--- packages/core/test/index.test-d.ts | 4 ++ 3 files changed, 66 insertions(+), 8 deletions(-) diff --git a/packages/core/package.json b/packages/core/package.json index 40de779..bbed239 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -60,7 +60,6 @@ "devDependencies": { "ava": "latest", "proxyquire": "latest", - "puppeteer-core": "25", "tinyspawn": "latest", "tsd": "latest" }, diff --git a/packages/core/src/index.d.ts b/packages/core/src/index.d.ts index fba5f83..f5a0251 100644 --- a/packages/core/src/index.d.ts +++ b/packages/core/src/index.d.ts @@ -1,6 +1,3 @@ -import type { HTTPResponse, Page } from 'puppeteer-core' with { - 'resolution-mode': 'import' -} import createGoogleClient from '@microlink/google' type GoogleClient = ReturnType @@ -158,11 +155,69 @@ interface Embed { [key: string]: unknown } -export type FunctionArgs = { - page: Page & { - metadata(): Promise - extract(rules: ExtractRules): Promise> +export interface HTTPResponse { + status(): number + statusText(): string + url(): string + ok(): boolean + headers(): Record + text(): Promise + json(): Promise +} + +/** Page handed to `microlink.function` callbacks. */ +export interface Page { + title(): Promise + url(): string + content(): Promise + $(selector: string): Promise + $$(selector: string): Promise + $eval(selector: string, fn: (el: Element) => T): Promise> + $$eval(selector: string, fn: (els: Element[]) => T): Promise> + evaluate( + fn: string | ((...args: any[]) => T), + ...args: any[] + ): Promise> + click(selector: string): Promise + type(selector: string, text: string): Promise + hover(selector: string): Promise + focus(selector: string): Promise + select(selector: string, ...values: string[]): Promise + waitForSelector( + selector: string, + options?: { visible?: boolean; hidden?: boolean; timeout?: number } + ): Promise + waitForFunction( + fn: string | ((...args: any[]) => unknown), + options?: { timeout?: number } + ): Promise + waitForNavigation(options?: { + waitUntil?: string + timeout?: number + }): Promise + waitForNetworkIdle(options?: { + idleTime?: number + timeout?: number + }): Promise + goto( + url: string, + options?: { waitUntil?: string; timeout?: number } + ): Promise + cookies(): Promise + keyboard: { + type(text: string): Promise + press(key: string): Promise } + mouse: { + click(x: number, y: number): Promise + move(x: number, y: number): Promise + } + metadata(): Promise + extract(rules: ExtractRules): Promise> +} + +export type FunctionArgs = { + page: Page response: HTTPResponse headers: Record url: string diff --git a/packages/core/test/index.test-d.ts b/packages/core/test/index.test-d.ts index 702d513..548f187 100644 --- a/packages/core/test/index.test-d.ts +++ b/packages/core/test/index.test-d.ts @@ -1,5 +1,6 @@ import { expectAssignable, expectType } from 'tsd' import create, { MicrolinkError } from '../src/index.js' +import type { FunctionArgs, Page } from '../src/index.js' type Asset = Awaited['screenshot']>> @@ -83,7 +84,10 @@ async function assertions (): Promise { const title = await client.function( 'https://example.com', async ({ page, response, headers, url }) => { + expectType(page) + expectType(page) expectType>(page.title()) + expectType>(page.content()) expectType(response.ok()) expectType>(headers) expectType(url) From 1bc0abcda9bf236419da9a31d48e0fb325aae46f Mon Sep 17 00:00:00 2001 From: Kiko Beats Date: Sun, 20 Sep 2026 19:11:56 +0200 Subject: [PATCH 2/2] fix(core): re-export puppeteer Page types Copying a Page stub into microlink.io duplicated puppeteer-core. Re-export the real types so the editor can generate from the same dts. Co-authored-by: Cursor --- packages/core/package.json | 1 + packages/core/src/index.d.ts | 71 ++++-------------------------- packages/core/test/index.test-d.ts | 6 +-- 3 files changed, 12 insertions(+), 66 deletions(-) diff --git a/packages/core/package.json b/packages/core/package.json index bbed239..40de779 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -60,6 +60,7 @@ "devDependencies": { "ava": "latest", "proxyquire": "latest", + "puppeteer-core": "25", "tinyspawn": "latest", "tsd": "latest" }, diff --git a/packages/core/src/index.d.ts b/packages/core/src/index.d.ts index f5a0251..a756475 100644 --- a/packages/core/src/index.d.ts +++ b/packages/core/src/index.d.ts @@ -1,5 +1,10 @@ +import type { HTTPResponse, Page } from 'puppeteer-core' with { + 'resolution-mode': 'import' +} import createGoogleClient from '@microlink/google' +export type { HTTPResponse, Page } + type GoogleClient = ReturnType /** @@ -155,69 +160,11 @@ interface Embed { [key: string]: unknown } -export interface HTTPResponse { - status(): number - statusText(): string - url(): string - ok(): boolean - headers(): Record - text(): Promise - json(): Promise -} - -/** Page handed to `microlink.function` callbacks. */ -export interface Page { - title(): Promise - url(): string - content(): Promise - $(selector: string): Promise - $$(selector: string): Promise - $eval(selector: string, fn: (el: Element) => T): Promise> - $$eval(selector: string, fn: (els: Element[]) => T): Promise> - evaluate( - fn: string | ((...args: any[]) => T), - ...args: any[] - ): Promise> - click(selector: string): Promise - type(selector: string, text: string): Promise - hover(selector: string): Promise - focus(selector: string): Promise - select(selector: string, ...values: string[]): Promise - waitForSelector( - selector: string, - options?: { visible?: boolean; hidden?: boolean; timeout?: number } - ): Promise - waitForFunction( - fn: string | ((...args: any[]) => unknown), - options?: { timeout?: number } - ): Promise - waitForNavigation(options?: { - waitUntil?: string - timeout?: number - }): Promise - waitForNetworkIdle(options?: { - idleTime?: number - timeout?: number - }): Promise - goto( - url: string, - options?: { waitUntil?: string; timeout?: number } - ): Promise - cookies(): Promise - keyboard: { - type(text: string): Promise - press(key: string): Promise - } - mouse: { - click(x: number, y: number): Promise - move(x: number, y: number): Promise - } - metadata(): Promise - extract(rules: ExtractRules): Promise> -} - export type FunctionArgs = { - page: Page + page: Page & { + metadata(): Promise + extract(rules: ExtractRules): Promise> + } response: HTTPResponse headers: Record url: string diff --git a/packages/core/test/index.test-d.ts b/packages/core/test/index.test-d.ts index 548f187..b8cfba2 100644 --- a/packages/core/test/index.test-d.ts +++ b/packages/core/test/index.test-d.ts @@ -1,6 +1,6 @@ import { expectAssignable, expectType } from 'tsd' import create, { MicrolinkError } from '../src/index.js' -import type { FunctionArgs, Page } from '../src/index.js' +import type { Page } from '../src/index.js' type Asset = Awaited['screenshot']>> @@ -84,10 +84,8 @@ async function assertions (): Promise { const title = await client.function( 'https://example.com', async ({ page, response, headers, url }) => { - expectType(page) - expectType(page) + expectAssignable(page) expectType>(page.title()) - expectType>(page.content()) expectType(response.ok()) expectType>(headers) expectType(url)