Published source
Download source ZIP
CH-J Server Manager
Browse directories and files for a specific application release.
Source is provided under the CH-J Proprietary Software License 1.14. Its availability does not change the license terms or grant additional rights.
1
"use strict";3
const fs = require("node:fs");4
const path = require("node:path");5
const crypto = require("node:crypto");6
const AdmZip = require("adm-zip");8
const projectRoot = path.resolve(__dirname, "..");9
const lock = JSON.parse(fs.readFileSync(path.join(projectRoot, "package-lock.json"), "utf8"));10
const outputPath = path.join(projectRoot, "THIRD_PARTY_NOTICES.txt");11
const packages = new Map();13
// Electron 43 downloads its runtime lazily. The build copies license files from14
// that runtime, so make the documented `npm ci` -> `npm run build:*` flow15
// deterministic on every supported OS without a platform-specific shell step.16
const electronExecutable = require("electron");17
if (!fs.statSync(electronExecutable, { throwIfNoEntry: false })?.isFile()) {18
throw new Error("Electron runtime is unavailable after dependency installation.");19
}21
function declaredLicense(value) {22
if (typeof value === "string") return value;23
if (Array.isArray(value)) return value.map(declaredLicense).filter(Boolean).join(" OR ");24
if (value && typeof value === "object") return String(value.type || value.name || "See included text");25
return "See included text";26
}28
function readLicense(directory) {29
const entries = fs.readdirSync(directory, { withFileTypes: true });30
const candidates = entries31
.filter((entry) => entry.isFile() && /^(licen[cs]e|copying|notice)(\..*)?$/i.test(entry.name))32
.sort((left, right) => left.name.localeCompare(right.name));33
if (candidates.length) {34
return candidates.map((entry) => ({ source: entry.name, text: fs.readFileSync(path.join(directory, entry.name), "utf8").trim() }));35
}36
const readme = entries.find((entry) => entry.isFile() && /^readme(?:\..*)?$/i.test(entry.name));37
if (readme) {38
const text = fs.readFileSync(path.join(directory, readme.name), "utf8");39
const match = text.match(/^#{1,3}\s+licen[cs]e\s*$[\s\S]*/im);40
if (match) return [{ source: `${readme.name} (License section)`, text: match[0].trim() }];41
}42
return [];43
}45
for (const [relative, metadata] of Object.entries(lock.packages || {})) {46
if (!relative.startsWith("node_modules/") || metadata.dev === true) continue;47
const directory = path.join(projectRoot, relative);48
const packagePath = path.join(directory, "package.json");49
if (!fs.statSync(packagePath, { throwIfNoEntry: false })?.isFile()) continue;50
const manifest = JSON.parse(fs.readFileSync(packagePath, "utf8"));51
const key = `${manifest.name}@${manifest.version}`;52
if (packages.has(key)) continue;53
const texts = readLicense(directory);54
if (!texts.length) throw new Error(`No distributable license text found for ${key}.`);55
packages.set(key, { key, license: declaredLicense(manifest.license || metadata.license), texts });56
}57
const bundledTigerLicense = path.join(projectRoot, "src", "main", "hashing", "vendor", "fbTiger", "LICENSE.txt");58
packages.set("fb-tiger-hash@1.0.0 (bundled source)", {59
key: "fb-tiger-hash@1.0.0 (bundled source)",60
license: "MIT",61
texts: [{ source: "src/main/hashing/vendor/fbTiger/LICENSE.txt", text: fs.readFileSync(bundledTigerLicense, "utf8").trim() }]62
});63
const bundledCityHashLicense = path.join(projectRoot, "src", "main", "hashing", "vendor", "cityHash", "LICENSE.txt");64
packages.set("google-cityhash (ported source)", {65
key: "google-cityhash (ported source)",66
license: "MIT",67
texts: [{ source: "src/main/hashing/vendor/cityHash/LICENSE.txt", text: fs.readFileSync(bundledCityHashLicense, "utf8").trim() }]68
});70
const separator = "=".repeat(78);71
const sections = [...packages.values()]72
.sort((left, right) => left.key.localeCompare(right.key))73
.map((entry) => {74
const body = entry.texts.map((item) => `Source: ${item.source}\n\n${item.text}`).join("\n\n");75
return `${separator}\n${entry.key}\nDeclared license: ${entry.license}\n${separator}\n\n${body}`;76
});77
const header = [78
"CH-J Server Manager — Third-Party Notices",79
"",80
"This file lists license texts for production Node.js dependencies bundled",81
"with the application. Electron and Chromium license files are distributed",82
"separately in the application's resources/licenses directory.",83
""84
].join("\n");85
fs.writeFileSync(outputPath, `${header}\n${sections.join("\n\n")}\n`, "utf8");87
const bundleDocuments = [88
{ name: "THIRD_PARTY_NOTICES.txt", path: outputPath, description: "Production Node.js dependency licenses" },89
{ name: "ELECTRON_LICENSE.txt", path: path.join(projectRoot, "node_modules", "electron", "dist", "LICENSE"), description: "Electron license" },90
{ name: "CHROMIUM_LICENSES.html", path: path.join(projectRoot, "node_modules", "electron", "dist", "LICENSES.chromium.html"), description: "Chromium and embedded component licenses" },91
{ name: "MONACO_LICENSE.txt", path: path.join(projectRoot, "node_modules", "monaco-editor", "LICENSE"), description: "Monaco Editor license" },92
{ name: "MONACO_THIRD_PARTY_NOTICES.txt", path: path.join(projectRoot, "node_modules", "monaco-editor", "ThirdPartyNotices.txt"), description: "Monaco Editor third-party notices" },93
{ name: "GOOGLE_CITYHASH_LICENSE.txt", path: bundledCityHashLicense, description: "Ported CityHash implementation license" },94
{ name: "FB_TIGER_HASH_LICENSE.txt", path: bundledTigerLicense, description: "Bundled Tiger/Tiger2 implementation license" }95
];96
for (const document of bundleDocuments) {97
if (!fs.statSync(document.path, { throwIfNoEntry: false })?.isFile()) throw new Error(`Missing third-party license document: ${document.path}`);98
document.data = fs.readFileSync(document.path);99
document.sha512 = crypto.createHash("sha512").update(document.data).digest("hex");100
}101
const bundleReadme = [102
"CH-J Server Manager — Complete Third-Party License Package",103
"",104
"This archive contains the license texts and notices for third-party software",105
"distributed by CH-J Server Manager Core and its bundled source components.",106
"This application edition is licensed separately under the CH-J Proprietary Software License, version 1.14.",107
"",108
"Contents:",109
...bundleDocuments.map((document) => `- ${document.name}: ${document.description}`),110
""111
].join("\n");112
const checksums = bundleDocuments.map((document) => `${document.sha512} ${document.name}`).join("\n") + "\n";113
const zip = new AdmZip();114
for (const document of [115
{ name: "README.txt", data: Buffer.from(bundleReadme, "utf8") },116
{ name: "SHA512SUMS.txt", data: Buffer.from(checksums, "utf8") },117
...bundleDocuments118
]) {119
zip.addFile(document.name, document.data, "", 0o644);120
const entry = zip.getEntry(document.name);121
if (entry) entry.header.time = new Date("2000-01-01T00:00:00Z");122
}123
const bundlePath = path.join(projectRoot, "THIRD_PARTY_LICENSES.zip");124
zip.writeZip(bundlePath);125
console.log(`Generated ${path.basename(outputPath)} for ${sections.length} package versions and ${path.basename(bundlePath)} with ${bundleDocuments.length} complete license documents.`);SHA-256: aad5c90c9d1b53deb2abd3ff26215ed99f009566ee0b629452d18e8c1f4003b1
Archive SHA-256: 5ac91caf4fa32a6fdb114f2430deed486fbe7489d5eea343d1f034169fafb5e0