From 96bc7af65c9fabde36472fefb2847e539e575221 Mon Sep 17 00:00:00 2001 From: Kiko Beats Date: Sun, 20 Sep 2026 18:23:37 +0200 Subject: [PATCH 1/2] feat(core): type page.metadata and page.extract Co-authored-by: Cursor --- packages/core/src/index.d.ts | 45 ++++++++++++++++++++++++++++-- packages/core/test/index.test-d.ts | 7 +++++ 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/packages/core/src/index.d.ts b/packages/core/src/index.d.ts index 7289319..706c161 100644 --- a/packages/core/src/index.d.ts +++ b/packages/core/src/index.d.ts @@ -111,9 +111,47 @@ interface Metadata { title?: string | null description?: string | null url?: string | null + author?: string | null + lang?: string | null + publisher?: string | null + date?: string | null + image?: Asset | null + logo?: Asset | null [key: string]: unknown } +/** Same shape as `?data=` / `microlink.extract` rules. */ +interface ExtractRule { + attr?: string | string[] | ExtractRules + evaluate?: string | (() => unknown) + selector?: string | string[] + selectorAll?: string | string[] + type?: + | 'audio' + | 'author' + | 'auto' + | 'boolean' + | 'date' + | 'description' + | 'email' + | 'image' + | 'ip' + | 'lang' + | 'logo' + | 'number' + | 'object' + | 'publisher' + | 'regexp' + | 'string' + | 'title' + | 'url' + | 'video' +} + +interface ExtractRules { + [field: string]: ExtractRule +} + interface Embed { html: string scripts?: unknown[] @@ -121,7 +159,10 @@ interface Embed { } export type FunctionArgs = { - page: Page + page: Page & { + metadata(): Promise + extract(rules: ExtractRules): Promise> + } response: HTTPResponse headers: Record url: string @@ -163,7 +204,7 @@ interface MicrolinkClient { audios (url: string, options?: CollectionOptions): Promise extract ( url: string, - rules: Record, + rules: ExtractRules, options?: Options ): Promise> screenshot (url: string, options?: ScreenshotOptions): Promise diff --git a/packages/core/test/index.test-d.ts b/packages/core/test/index.test-d.ts index cce5d46..2ebfb34 100644 --- a/packages/core/test/index.test-d.ts +++ b/packages/core/test/index.test-d.ts @@ -79,6 +79,13 @@ async function assertions (): Promise { expectType(response.ok()) expectType>(headers) expectType(url) + const metadata = await page.metadata() + expectType(metadata.title) + expectType>( + await page.extract({ + title: { selector: 'h1', type: 'string' } + }) + ) return page.title() } ) From e6c13697c38783dc7a2c27297ce4132341c9fff0 Mon Sep 17 00:00:00 2001 From: Kiko Beats Date: Sun, 20 Sep 2026 18:34:57 +0200 Subject: [PATCH 2/2] fix(core): allow extract fallback rule arrays Co-authored-by: Cursor --- packages/core/src/index.d.ts | 2 +- packages/core/test/index.test-d.ts | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/core/src/index.d.ts b/packages/core/src/index.d.ts index 706c161..fba5f83 100644 --- a/packages/core/src/index.d.ts +++ b/packages/core/src/index.d.ts @@ -149,7 +149,7 @@ interface ExtractRule { } interface ExtractRules { - [field: string]: ExtractRule + [field: string]: ExtractRule | ExtractRule[] } interface Embed { diff --git a/packages/core/test/index.test-d.ts b/packages/core/test/index.test-d.ts index 2ebfb34..702d513 100644 --- a/packages/core/test/index.test-d.ts +++ b/packages/core/test/index.test-d.ts @@ -62,6 +62,14 @@ async function assertions (): Promise { avatar: { selector: 'img', attr: 'src', type: 'image' } }) expectAssignable>(data) + expectAssignable>( + await client.extract('https://example.com', { + avatar: [ + { selector: 'meta[property="og:image"]', attr: 'content', type: 'image' }, + { selector: 'img', attr: 'src', type: 'image' } + ] + }) + ) const news = await client.search('coffee', { type: 'news', limit: 3 }) expectAssignable<{ results: Array<{ publisher: string }> }>(news) @@ -83,7 +91,11 @@ async function assertions (): Promise { expectType(metadata.title) expectType>( await page.extract({ - title: { selector: 'h1', type: 'string' } + title: { selector: 'h1', type: 'string' }, + avatar: [ + { selector: 'meta[property="og:image"]', attr: 'content', type: 'image' }, + { selector: 'img', attr: 'src', type: 'image' } + ] }) ) return page.title()