lody 0.62.0 → 0.63.0

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.
@@ -0,0 +1,80 @@
1
+ import { createHash } from "node:crypto";
2
+ import { readFile, mkdir, writeFile, rename } from "node:fs/promises";
3
+ import os__default from "node:os";
4
+ import path__default from "node:path";
5
+ import process from "node:process";
6
+ const reviewViewerVersion = "0.63.0";
7
+ const reviewViewerSha256 = "ea17e6d80a981066069ee62bbfa48de9f2df5adaf8ced752190476b5f76157f6";
8
+ const reviewViewerFileName = "standalone.html";
9
+ const DEFAULT_CDN_BASES = ["https://cdn.jsdelivr.net/npm", "https://unpkg.com"];
10
+ function cacheDir() {
11
+ return path__default.join(os__default.homedir(), ".lody", "code-review-viewer");
12
+ }
13
+ function cachePath() {
14
+ return path__default.join(cacheDir(), `${reviewViewerVersion}.html`);
15
+ }
16
+ function sha256(buffer) {
17
+ return createHash("sha256").update(buffer).digest("hex");
18
+ }
19
+ function isUrl(source) {
20
+ return /^https?:\/\//i.test(source);
21
+ }
22
+ async function loadSource(source) {
23
+ if (isUrl(source)) {
24
+ const response = await fetch(source, { signal: AbortSignal.timeout(3e4) });
25
+ if (!response.ok) {
26
+ throw new Error(`HTTP ${response.status}`);
27
+ }
28
+ return Buffer.from(await response.arrayBuffer());
29
+ }
30
+ return readFile(path__default.resolve(source));
31
+ }
32
+ async function writeCache(buffer) {
33
+ try {
34
+ await mkdir(cacheDir(), { recursive: true });
35
+ const tmp = `${cachePath()}.tmp-${process.pid}`;
36
+ await writeFile(tmp, buffer);
37
+ await rename(tmp, cachePath());
38
+ } catch {
39
+ }
40
+ }
41
+ async function resolveReviewViewerTemplate() {
42
+ try {
43
+ const cached = await readFile(cachePath());
44
+ if (sha256(cached) === reviewViewerSha256) {
45
+ return cached.toString("utf8");
46
+ }
47
+ } catch {
48
+ }
49
+ const override = process.env.LODY_REVIEW_VIEWER?.trim();
50
+ const sources = override ? [override] : DEFAULT_CDN_BASES.map(
51
+ (base) => `${base}/lody-code-review-viewer@${reviewViewerVersion}/${reviewViewerFileName}`
52
+ );
53
+ const failures = [];
54
+ for (const source of sources) {
55
+ try {
56
+ const buffer = await loadSource(source);
57
+ const actual = sha256(buffer);
58
+ if (actual !== reviewViewerSha256) {
59
+ failures.push(
60
+ `${source}: sha256 mismatch (expected ${reviewViewerSha256.slice(0, 12)}\u2026, got ${actual.slice(
61
+ 0,
62
+ 12
63
+ )}\u2026)`
64
+ );
65
+ continue;
66
+ }
67
+ await writeCache(buffer);
68
+ return buffer.toString("utf8");
69
+ } catch (error) {
70
+ failures.push(`${source}: ${error instanceof Error ? error.message : String(error)}`);
71
+ }
72
+ }
73
+ throw new Error(
74
+ `Could not obtain the code-review viewer (lody-code-review-viewer@${reviewViewerVersion}).
75
+ ` + failures.map((line) => ` - ${line}`).join("\n") + "\nIf you are offline or behind a firewall, download standalone.html for this version and point LODY_REVIEW_VIEWER at it (a file path or URL)."
76
+ );
77
+ }
78
+ export {
79
+ resolveReviewViewerTemplate
80
+ };