File size: 4,390 Bytes
4d7e26e
 
 
2b30920
df57208
4d7e26e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
df57208
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4d7e26e
 
 
 
 
 
aac63b8
 
4d7e26e
 
 
 
2b30920
4d7e26e
19a019e
 
2b30920
19a019e
4d7e26e
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import { createHash } from "node:crypto";
import { mkdirSync, writeFileSync } from "node:fs";
import { get } from "node:https";
import { dirname, join } from "node:path";
import { gunzipSync } from "node:zlib";

const output = process.argv[2] || "static/vendor";
mkdirSync(output, { recursive: true });
function download(url, redirects = 0) {
  return new Promise((resolve, reject) => {
    const request = get(url, (response) => {
    if (response.statusCode >= 300 && response.statusCode < 400 && response.headers.location && redirects < 5) {
      response.resume();
      return download(new URL(response.headers.location, url), redirects + 1).then(resolve, reject);
    }
    if (response.statusCode !== 200) {
      response.resume();
      return reject(new Error(`${url}: HTTP ${response.statusCode}`));
    }
    const chunks = [];
    response.on("data", (chunk) => chunks.push(chunk));
    response.on("end", () => resolve(Buffer.concat(chunks)));
    response.on("error", reject);
    });
    request.setTimeout(60000, () => request.destroy(new Error(`${url}: request timed out`)));
    request.on("error", reject);
  });
}

async function downloadWithRetry(url) {
  let lastError;
  for (let attempt = 0; attempt < 4; attempt++) {
    try { return await download(url); }
    catch (error) {
      lastError = error;
      if (attempt < 3) await new Promise((resolve) => setTimeout(resolve, 1000 * (2 ** attempt)));
    }
  }
  throw lastError;
}

async function main() {
const pdfArchive = await downloadWithRetry("https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-6.2.108.tgz");
const pdfArchiveHash = createHash("sha256").update(pdfArchive).digest("hex");
if (pdfArchiveHash !== "b3e68d5cda70551a90b3f771419d379e20fc788ce056fa32de73608e01df47f4") throw new Error(`pdfjs-dist archive SHA-256 ${pdfArchiveHash} does not match`);
const tar = gunzipSync(pdfArchive);
for (let offset = 0; offset + 512 <= tar.length;) {
  const header = tar.subarray(offset, offset + 512), name = header.subarray(0, 100).toString().replace(/\0.*$/, "");
  if (!name) break;
  const size = parseInt(header.subarray(124, 136).toString().replace(/\0.*$/, "").trim() || "0", 8);
  const relative = name.replace(/^package\//, "");
  if ((relative.startsWith("cmaps/") || relative.startsWith("standard_fonts/") || relative.startsWith("wasm/")) && !relative.endsWith("/")) {
    const target = join(output, relative);
    mkdirSync(dirname(target), { recursive: true });
    writeFileSync(target, tar.subarray(offset + 512, offset + 512 + size));
  }
  offset += 512 + Math.ceil(size / 512) * 512;
}
for (const [url, target, expected] of [
  ["https://cdn.jsdelivr.net/npm/pdfjs-dist@6.2.108/build/pdf.min.mjs", "pdf.min.mjs", "e0be3863c23c8af2305b16548febd58e7f8874a460253317d7771cddbc1c0f6d"],
  ["https://cdn.jsdelivr.net/npm/pdfjs-dist@6.2.108/build/pdf.worker.min.mjs", "pdf.worker.min.mjs", "0613f41490dd6aaceed7a93fbbd38c85e6d6aa60474b6588c6e7709cfbe18cb3"],
  ["https://cdn.jsdelivr.net/npm/epubjs@0.3.93/dist/epub.min.js", "epub.min.js", "06eae15745107b4aa508c95538275251f69bfb9f1175621fc458d9f42ed082d4"],
  ["https://cdn.jsdelivr.net/npm/marked@18.0.10/lib/marked.umd.js", "marked.min.js", "eaccee2fb9fb3b2c09e873a5504da82507850d9e677bd720122ac49e2a03982a"],
  ["https://cdn.jsdelivr.net/npm/dompurify@3.4.14/dist/purify.min.js", "purify.min.js", "c2f26ea4fc0d88141c9aa430eb515ac86fce59418ceebd85fa475b87a8d6c3e6"],
  ["https://cdn.jsdelivr.net/npm/jszip@3.10.1/dist/jszip.min.js", "jszip.min.js", "acc7e41455a80765b5fd9c7ee1b8078a6d160bbbca455aeae854de65c947d59e"],
  ["https://cdn.jsdelivr.net/npm/docx-preview@0.3.6/dist/docx-preview.min.js", "docx-preview.min.js", "3573b8d993442316042e95c782338b503b2a7cd573d336db894b87799c9d3097"],
]) {
  const bytes = await downloadWithRetry(url);
  const actual = createHash("sha256").update(bytes).digest("hex");
  if (actual !== expected) throw new Error(`${url}: SHA-256 ${actual} does not match ${expected}`);
  mkdirSync(dirname(join(output, target)), { recursive: true });
  writeFileSync(join(output, target), bytes);
  const dot = target.lastIndexOf(".");
  const versioned = `${target.slice(0, dot)}.${actual.slice(0, 12)}${target.slice(dot)}`;
  mkdirSync(dirname(join(output, versioned)), { recursive: true });
  writeFileSync(join(output, versioned), bytes);
}
}

main().catch((error) => { console.error(error); process.exitCode = 1; });