Skip to content

Commit d545ccb

Browse files
committed
v5.0.1 Dynamically import puppeteer
1 parent d593ec9 commit d545ccb

File tree

4 files changed

+50
-6
lines changed

4 files changed

+50
-6
lines changed

package-lock.json

Lines changed: 10 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "metafetch",
33
"description": "Metafetch fetches a given URL's title, description, images, links etc.",
4-
"version": "5.0.0",
4+
"version": "5.0.1",
55
"homepage": "https://github.com/brahma-dev/metafetch",
66
"repository": {
77
"type": "git",
@@ -25,7 +25,12 @@
2525
"linkedom": "^0.18.11"
2626
},
2727
"peerDependencies": {
28-
"puppeteer": "^24.16.1"
28+
"puppeteer": ">=22.0.0 <25.0.0"
29+
},
30+
"peerDependenciesMeta": {
31+
"puppeteer": {
32+
"optional": true
33+
}
2934
},
3035
"devDependencies": {
3136
"@istanbuljs/nyc-config-typescript": "^1.0.2",

src/index.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { parseHTML } from 'linkedom';
22
import type { Document } from 'linkedom';
3-
import puppeteer from 'puppeteer';
43

54
/**
65
* The shape of the response object returned by Metafetch.
@@ -80,6 +79,14 @@ export class Metafetch {
8079
return this.#userAgent;
8180
}
8281

82+
/**
83+
* Wrapper for dynamic import of puppeteer to improve testability.
84+
* @private
85+
*/
86+
private async _getPuppeteer() {
87+
return import('puppeteer');
88+
}
89+
8390
/**
8491
* Fetches and parses metadata from a given URL.
8592
* @param url The URL to fetch.
@@ -112,6 +119,15 @@ export class Metafetch {
112119
let encoding: string;
113120

114121
if (options.render) {
122+
let puppeteer;
123+
try {
124+
const puppeteerModule = await this._getPuppeteer();
125+
puppeteer = puppeteerModule.default;
126+
} catch (err) {
127+
throw new Error(
128+
'The "render" option requires the "puppeteer" package. Please install it (`npm install puppeteer`) and try again.'
129+
);
130+
}
115131
const browser = await puppeteer.launch({
116132
headless: true, args: [
117133
'--no-sandbox',

test/test.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ describe('Metafetch: Optimized Tests', () => {
3737
res.setHeader('Content-Type', 'text/html; charset=iso-8859-1').end('<body></body>');
3838
return;
3939
case '/charset-meta':
40-
res.setHeader('Content-Type', 'text/html');
40+
res.setHeader('Content-Type', 'text/html');
4141
body = '<head><meta charset="windows-1252"></head>';
4242
break;
4343
case '/base-tag':
@@ -470,6 +470,21 @@ describe('Metafetch: Optimized Tests', () => {
470470
expect(err.message).to.equal("Received an empty response body.");
471471
}
472472
});
473+
474+
it('should throw a helpful error when puppeteer fails to import', async () => {
475+
const newInstance = new Metafetch();
476+
// Stub the private method to simulate an import failure
477+
const importStub = sinon.stub(newInstance as any, '_getPuppeteer').rejects(new Error('Simulated import failure'));
478+
479+
try {
480+
await newInstance.fetch(`${BASE_URL}/page`, { render: true });
481+
throw new Error("Test failed: Metafetch should have thrown an error.");
482+
} catch (err: any) {
483+
expect(err.message).to.equal('The "render" option requires the "puppeteer" package. Please install it (`npm install puppeteer`) and try again.');
484+
} finally {
485+
importStub.restore();
486+
}
487+
});
473488
});
474489

475490
describe('Request Retries', () => {

0 commit comments

Comments
 (0)