@pagepocket/cli 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # @pagepocket/cli
2
+
3
+ CLI for capturing offline snapshots of web pages. It fetches HTML, records network
4
+ responses, downloads assets, rewrites links to local files, and injects a replay
5
+ script so the snapshot works offline.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm i -g @pagepocket/cli
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ```bash
16
+ pp https://example.com
17
+ pp https://example.com -o ./snapshots
18
+ ```
19
+
20
+ ## Output
21
+
22
+ Snapshots are written to the current directory by default:
23
+
24
+ - `*.html`: offline snapshot page
25
+ - `*.requests.json`: recorded requests/responses
26
+ - `*_files/`: downloaded assets
27
+
28
+ ## Configuration
29
+
30
+ Environment variables:
31
+
32
+ - `PAGEPOCKET_FETCH_TIMEOUT_MS` (default: `60000`)
33
+ - `PAGEPOCKET_FETCH_HEADERS` (JSON string of extra headers)
34
+
35
+ ## Development
36
+
37
+ ```bash
38
+ pnpm install
39
+ pnpm --filter @pagepocket/cli build
40
+ ```
package/dist/cli.js CHANGED
@@ -5,14 +5,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const node_path_1 = __importDefault(require("node:path"));
7
7
  const core_1 = require("@oclif/core");
8
- const chalk_1 = __importDefault(require("chalk"));
9
8
  const lib_1 = require("@pagepocket/lib");
10
- const with_spinner_1 = require("./utils/with-spinner");
11
- const build_snapshot_data_1 = require("./stages/build-snapshot-data");
12
- const capture_network_1 = require("./stages/capture-network");
9
+ const lighterceptor_adapter_1 = require("@pagepocket/lighterceptor-adapter");
10
+ const chalk_1 = __importDefault(require("chalk"));
13
11
  const fetch_html_1 = require("./stages/fetch-html");
14
12
  const prepare_output_1 = require("./stages/prepare-output");
15
13
  const write_snapshot_1 = require("./stages/write-snapshot");
14
+ const with_spinner_1 = require("./utils/with-spinner");
16
15
  class PagepocketCommand extends core_1.Command {
17
16
  async run() {
18
17
  const { args, flags } = await this.parse(PagepocketCommand);
@@ -39,48 +38,32 @@ class PagepocketCommand extends core_1.Command {
39
38
  throw new Error("Invalid PAGEPOCKET_FETCH_HEADERS JSON.");
40
39
  }
41
40
  })();
42
- const fetchXhrRecords = [];
43
41
  const fetched = await (0, with_spinner_1.withSpinner)(async () => (0, fetch_html_1.fetchHtml)(targetUrl, fetchTimeoutMs, headersOverride), "Fetching the target HTML");
44
- const networkStage = await (async () => {
45
- try {
46
- return await (0, with_spinner_1.withSpinner)(async () => (0, capture_network_1.captureNetwork)(targetUrl, fetched.title), "Capturing network requests with lighterceptor");
47
- }
48
- catch {
49
- return {
50
- networkRecords: [],
51
- lighterceptorNetworkRecords: [],
52
- capturedTitle: undefined,
53
- title: fetched.title
54
- };
55
- }
56
- })();
57
- const outputPaths = await (0, with_spinner_1.withSpinner)(async () => (0, prepare_output_1.prepareOutputPaths)(networkStage.title, outputFlag), "Preparing output paths");
58
- const downloadStage = await (0, with_spinner_1.withSpinner)(async () => {
42
+ const { outputPaths, snapshotData, snapshotHtml } = await (0, with_spinner_1.withSpinner)(async () => {
59
43
  const originalCwd = process.cwd();
44
+ const interceptor = new lighterceptor_adapter_1.LighterceptorAdapter({ title: fetched.title });
45
+ const snapshotSeed = await interceptor.run(targetUrl);
46
+ const outputPaths = await (0, prepare_output_1.prepareOutputPaths)(snapshotSeed.title, outputFlag);
60
47
  const shouldRestoreCwd = outputPaths.baseDir !== originalCwd;
61
48
  try {
62
49
  if (shouldRestoreCwd) {
63
50
  process.chdir(outputPaths.baseDir);
64
51
  }
65
- const seedSnapshot = {
66
- url: targetUrl,
67
- title: networkStage.title,
68
- capturedAt: new Date().toISOString(),
69
- fetchXhrRecords,
70
- networkRecords: networkStage.lighterceptorNetworkRecords,
71
- resources: []
72
- };
73
- const pagepocket = new lib_1.PagePocket(fetched.html, seedSnapshot, {
74
- assetsDirName: outputPaths.assetsDirName,
52
+ const pagepocket = new lib_1.PagePocket(fetched.html, snapshotSeed, {
75
53
  baseUrl: targetUrl,
54
+ assetsDirName: outputPaths.assetsDirName,
76
55
  requestsPath: node_path_1.default.basename(outputPaths.outputRequestsPath)
77
56
  });
78
- const snapshotHtml = await pagepocket.put();
57
+ const pageData = await pagepocket.put();
58
+ const snapshotData = {
59
+ ...snapshotSeed,
60
+ title: pageData.title,
61
+ resources: pagepocket.resources
62
+ };
79
63
  return {
80
- snapshotHtml,
81
- resourceMeta: pagepocket.resources,
82
- downloadedCount: pagepocket.downloadedCount,
83
- failedCount: pagepocket.failedCount
64
+ outputPaths,
65
+ snapshotData,
66
+ snapshotHtml: pageData.content
84
67
  };
85
68
  }
86
69
  finally {
@@ -94,19 +77,12 @@ class PagepocketCommand extends core_1.Command {
94
77
  }
95
78
  }
96
79
  }, "Downloading resources");
97
- const snapshotData = await (0, with_spinner_1.withSpinner)(async () => (0, build_snapshot_data_1.buildSnapshotData)({
98
- targetUrl,
99
- title: networkStage.title,
100
- fetchXhrRecords,
101
- lighterceptorNetworkRecords: networkStage.lighterceptorNetworkRecords,
102
- resources: downloadStage.resourceMeta
103
- }), "Preparing snapshot HTML");
104
80
  await (0, with_spinner_1.withSpinner)(async () => {
105
81
  await (0, write_snapshot_1.writeSnapshotFiles)({
106
82
  outputRequestsPath: outputPaths.outputRequestsPath,
107
83
  outputHtmlPath: outputPaths.outputHtmlPath,
108
84
  snapshotData,
109
- snapshotHtml: downloadStage.snapshotHtml
85
+ snapshotHtml: snapshotHtml
110
86
  });
111
87
  }, "Writing snapshot files");
112
88
  this.log(chalk_1.default.green("All done! Snapshot created."));
@@ -7,7 +7,7 @@ const buildSnapshotData = (input) => {
7
7
  title: input.title,
8
8
  capturedAt: new Date().toISOString(),
9
9
  fetchXhrRecords: input.fetchXhrRecords,
10
- networkRecords: input.lighterceptorNetworkRecords,
10
+ networkRecords: input.capturedNetworkRecords,
11
11
  resources: input.resources
12
12
  };
13
13
  };
@@ -1,17 +1,17 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.captureNetwork = void 0;
4
- const lighterceptor_1 = require("lighterceptor");
5
4
  const lib_1 = require("@pagepocket/lib");
5
+ const lighterceptor_1 = require("@pagepocket/lighterceptor");
6
6
  const captureNetwork = async (targetUrl, currentTitle) => {
7
7
  const result = await new lighterceptor_1.Lighterceptor(targetUrl, { recursion: true }).run();
8
- const lighterceptorNetworkRecords = (result.networkRecords ?? []);
9
- const networkRecords = (0, lib_1.mapLighterceptorRecords)(lighterceptorNetworkRecords);
8
+ const capturedNetworkRecords = (result.networkRecords ?? []);
9
+ const networkRecords = (0, lib_1.mapCapturedNetworkRecords)(capturedNetworkRecords);
10
10
  const capturedTitle = result.title;
11
11
  const title = currentTitle === "snapshot" && capturedTitle ? capturedTitle : currentTitle;
12
12
  return {
13
13
  networkRecords,
14
- lighterceptorNetworkRecords,
14
+ capturedNetworkRecords,
15
15
  capturedTitle,
16
16
  title
17
17
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pagepocket/cli",
3
- "version": "0.4.0",
4
- "description": "",
3
+ "version": "0.4.2",
4
+ "description": "CLI for capturing offline snapshots of web pages.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
7
7
  "pp": "dist/index.js"
@@ -14,16 +14,16 @@
14
14
  "license": "ISC",
15
15
  "dependencies": {
16
16
  "@oclif/core": "^4.0.9",
17
- "cheerio": "^1.0.0-rc.12",
18
17
  "chalk": "^4.1.2",
18
+ "cheerio": "^1.0.0-rc.12",
19
19
  "got": "^11.8.6",
20
20
  "ora": "^9.0.0",
21
- "@pagepocket/lib": "0.4.0",
22
- "lighterceptor": "npm:@pagepocket/lighterceptor@0.4.0"
21
+ "@pagepocket/lighterceptor": "0.4.2",
22
+ "@pagepocket/lib": "0.4.2",
23
+ "@pagepocket/lighterceptor-adapter": "0.4.2"
23
24
  },
24
25
  "devDependencies": {
25
26
  "@types/node": "^20.11.30",
26
- "prettier": "^3.7.4",
27
27
  "tsx": "^4.19.3",
28
28
  "typescript": "^5.4.5"
29
29
  },
@@ -36,8 +36,6 @@
36
36
  },
37
37
  "scripts": {
38
38
  "build": "tsc",
39
- "format": "prettier --write .",
40
- "format:check": "prettier --check .",
41
39
  "start": "node dist/index.js",
42
40
  "test": "tsx --test specs/**/*.test.ts"
43
41
  }