CH-J ToolsSSH를 통한 서버 관리
메뉴
공개된 소스

CH-J Tools

특정 애플리케이션 릴리스의 디렉터리와 파일을 살펴보세요.

소스 ZIP 다운로드
CH-J / Server Manager 406 개 파일
core-20261024T135205Z-7c487d719de2 추가됨: · 빌드됨:
generateThirdPartyNotices.js 추가됨: 날짜 기록 없음 7.6 KB · 139 줄
코드 파일 다운로드
1"use strict";
3const fs = require("node:fs");
4const path = require("node:path");
5const crypto = require("node:crypto");
6const AdmZip = require("adm-zip");
8const projectRoot = path.resolve(__dirname, "..");
9const lock = JSON.parse(fs.readFileSync(path.join(projectRoot, "package-lock.json"), "utf8"));
10const outputPath = path.join(projectRoot, "THIRD_PARTY_NOTICES.txt");
11const packages = new Map();
13// Electron 43 downloads its runtime lazily. The build copies license files from
14// that runtime, so make the documented `npm ci` -> `npm run build:*` flow
15// deterministic on every supported OS without a platform-specific shell step.
16const electronExecutable = require("electron");
17if (!fs.statSync(electronExecutable, { throwIfNoEntry: false })?.isFile()) {
18 throw new Error("Electron runtime is unavailable after dependency installation.");
21function 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";
28function readLicense(directory) {
29 const entries = fs.readdirSync(directory, { withFileTypes: true });
30 const candidates = entries
31 .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 [];
45for (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 });
57const bundledTigerLicense = path.join(projectRoot, "src", "main", "hashing", "vendor", "fbTiger", "LICENSE.txt");
58packages.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});
63const bundledCityHashLicense = path.join(projectRoot, "src", "main", "hashing", "vendor", "cityHash", "LICENSE.txt");
64packages.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});
69const bundledLucideLicense = path.join(projectRoot, "src", "renderer", "vendor", "lucide", "LICENSE.txt");
70packages.set("lucide-static@1.52.0 (bundled navigation icons)", {
71 key: "lucide-static@1.52.0 (bundled navigation icons)",
72 license: "ISC",
73 texts: [{ source: "src/renderer/vendor/lucide/LICENSE.txt", text: fs.readFileSync(bundledLucideLicense, "utf8").trim() }]
74});
76const separator = "=".repeat(78);
77const sections = [...packages.values()]
78 .sort((left, right) => left.key.localeCompare(right.key))
79 .map((entry) => {
80 const body = entry.texts.map((item) => `Source: ${item.source}\n\n${item.text}`).join("\n\n");
81 return `${separator}\n${entry.key}\nDeclared license: ${entry.license}\n${separator}\n\n${body}`;
82 });
83const header = [
84 "CH-J Server Manager — Third-Party Notices",
85 "",
86 "This file lists license texts for production Node.js dependencies bundled",
87 "with the application. Electron and Chromium license files are distributed",
88 "separately in the application's resources/licenses directory.",
89 ""
90].join("\n");
91fs.writeFileSync(outputPath, `${header}\n${sections.join("\n\n")}\n`, "utf8");
93const bundleDocuments = [
94 { name: "THIRD_PARTY_NOTICES.txt", path: outputPath, description: "Production Node.js dependency licenses" },
95 { name: "ELECTRON_LICENSE.txt", path: path.join(projectRoot, "node_modules", "electron", "dist", "LICENSE"), description: "Electron license" },
96 { name: "CHROMIUM_LICENSES.html", path: path.join(projectRoot, "node_modules", "electron", "dist", "LICENSES.chromium.html"), description: "Chromium and embedded component licenses" },
97 { name: "MONACO_LICENSE.txt", path: path.join(projectRoot, "node_modules", "monaco-editor", "LICENSE"), description: "Monaco Editor license" },
98 { name: "MONACO_THIRD_PARTY_NOTICES.txt", path: path.join(projectRoot, "node_modules", "monaco-editor", "ThirdPartyNotices.txt"), description: "Monaco Editor third-party notices" },
99 { name: "GOOGLE_CITYHASH_LICENSE.txt", path: bundledCityHashLicense, description: "Ported CityHash implementation license" },
100 { name: "FB_TIGER_HASH_LICENSE.txt", path: bundledTigerLicense, description: "Bundled Tiger/Tiger2 implementation license" },
101 { name: "LUCIDE_ICONS_LICENSE.txt", path: bundledLucideLicense, description: "Bundled Lucide navigation icons license" }
102];
103const nativeLicenseRoot = path.join(projectRoot, "scripts", "native", "licenses");
104if (fs.existsSync(nativeLicenseRoot)) {
105 for (const platform of fs.readdirSync(nativeLicenseRoot)) {
106 const dir = path.join(nativeLicenseRoot, platform);
107 for (const name of fs.readdirSync(dir)) bundleDocuments.push({ name: `native/${platform}/${name}`, path: path.join(dir, name), description: "Bundled native HTTP transport license/provenance" });
108 }
110for (const document of bundleDocuments) {
111 if (!fs.statSync(document.path, { throwIfNoEntry: false })?.isFile()) throw new Error(`Missing third-party license document: ${document.path}`);
112 document.data = fs.readFileSync(document.path);
113 document.sha512 = crypto.createHash("sha512").update(document.data).digest("hex");
115const bundleReadme = [
116 "CH-J Server Manager — Complete Third-Party License Package",
117 "",
118 "This archive contains the license texts and notices for third-party software",
119 "distributed by CH-J Server Manager Core and its bundled source components.",
120 "This application edition is licensed separately under the CH-J Proprietary Software License, version 1.14.",
121 "",
122 "Contents:",
123 ...bundleDocuments.map((document) => `- ${document.name}: ${document.description}`),
124 ""
125].join("\n");
126const checksums = bundleDocuments.map((document) => `${document.sha512} ${document.name}`).join("\n") + "\n";
127const zip = new AdmZip();
128for (const document of [
129 { name: "README.txt", data: Buffer.from(bundleReadme, "utf8") },
130 { name: "SHA512SUMS.txt", data: Buffer.from(checksums, "utf8") },
131 ...bundleDocuments
132]) {
133 zip.addFile(document.name, document.data, "", 0o644);
134 const entry = zip.getEntry(document.name);
135 if (entry) entry.header.time = new Date("2000-01-01T00:00:00Z");
137const bundlePath = path.join(projectRoot, "THIRD_PARTY_LICENSES.zip");
138zip.writeZip(bundlePath);
139console.log(`Generated ${path.basename(outputPath)} for ${sections.length} package versions and ${path.basename(bundlePath)} with ${bundleDocuments.length} complete license documents.`);
SHA-256a5b9bc9253152a4a501b393e633edd7e0ef935bd5dc027b1ebed7a57005fbcca

CH-J Proprietary Software License 1.14 · 소스는 CH-J Proprietary Software License 1.14에 따라 제공됩니다. 소스를 공개한다고 해서 라이선스 조항이 바뀌거나 추가 권리가 부여되지는 않습니다.

압축 파일 SHA-256476ed8aef0f1e96a5acdf223127b6692acdf4492eeaf5d0816b6e2a634fbbda6
파일