Skip to content

Commit 6d41cb1

Browse files
committed
feat: create @amazeelabs/save-webpage
1 parent 92c42d2 commit 6d41cb1

File tree

8 files changed

+248
-2
lines changed

8 files changed

+248
-2
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module.exports = {
2+
extends: ['@amazeelabs/eslint-config'],
3+
root: true,
4+
};
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
build
2+
node_modules
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
!build
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"@amazeelabs/prettier-config"
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "@amazeelabs/save-webpage",
3+
"version": "1.0.0",
4+
"description": "Saves a webpage with all resources.",
5+
"type": "module",
6+
"main": "./build/index.js",
7+
"types": "./build/index.d.ts",
8+
"private": false,
9+
"publishConfig": {
10+
"access": "public"
11+
},
12+
"scripts": {
13+
"build": "rm -rf build && tsc",
14+
"test:static": "tsc --noEmit && eslint '**/*.{ts,tsx,js,jsx}' --ignore-path='./.gitignore'"
15+
},
16+
"dependencies": {
17+
"website-scraper": "^5.3.1"
18+
},
19+
"devDependencies": {
20+
"@amazeelabs/eslint-config": "1.4.43",
21+
"@amazeelabs/prettier-config": "1.1.3",
22+
"@types/website-scraper": "^1.2.10",
23+
"typescript": "5.3.3"
24+
},
25+
"keywords": [],
26+
"author": "AmazeeLabs <[email protected]>"
27+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import * as scrape from 'website-scraper';
2+
3+
export async function saveWebpage(args: {
4+
/**
5+
* URL of the target webpage.
6+
*/
7+
url: string;
8+
/**
9+
* Replaces the actual webpage content.
10+
*/
11+
content?: string;
12+
/**
13+
* Path to directory where downloaded files will be saved. Must not exist.
14+
*/
15+
directory: string;
16+
}): Promise<void> {
17+
await scrape({
18+
directory: args.directory,
19+
urls: [args.url],
20+
plugins: args.content ? [new ReplaceContentPlugin(args.content)] : [],
21+
});
22+
}
23+
24+
// Replaces the first request response with given content.
25+
class ReplaceContentPlugin {
26+
isFirstRequest = true;
27+
28+
constructor(public firstRequestResponse: string) {}
29+
30+
apply(
31+
registerAction: (
32+
event: 'afterResponse',
33+
handler: <T>(args: { response: T }) => Promise<
34+
| T
35+
| {
36+
body: string;
37+
encoding: 'utf8';
38+
metadata: {};
39+
}
40+
>,
41+
) => void,
42+
): void {
43+
registerAction('afterResponse', async ({ response }) => {
44+
if (this.isFirstRequest) {
45+
this.isFirstRequest = false;
46+
return {
47+
body: this.firstRequestResponse,
48+
encoding: 'utf8',
49+
metadata: {},
50+
};
51+
} else {
52+
this.isFirstRequest = false;
53+
return response;
54+
}
55+
});
56+
}
57+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"compilerOptions": {
3+
"declaration": true,
4+
"target": "esnext",
5+
"module": "esnext",
6+
"strict": true,
7+
"skipLibCheck": true,
8+
"outDir": "build"
9+
},
10+
"include": ["src"],
11+
"$schema": "https://json.schemastore.org/tsconfig"
12+
}

pnpm-lock.yaml

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

0 commit comments

Comments
 (0)