UNPKG

@deskthing/cli

Version:
128 lines (112 loc) 4.38 kB
import { createHash } from "crypto"; import { existsSync, readFileSync, writeFileSync } from "fs"; import { join } from "path"; import { loadConfigs } from "./config"; import { sanitizeClient } from "./sanitizeData"; import { ClientLatestJSONLatest, ClientReleaseMeta } from "@deskthing/types"; import { getReleaseFilePath } from "../utils/filePaths"; import { validateRepoUrl } from "../utils/validateRepoUrl"; const getLatestReleasesFromGithubURLs = ( releaseAssetId: string, potentialUrls: string[] ): string => { for (const url of potentialUrls) { try { // Match GitHub repository URLs const githubMatch = url.match(/github\.com\/([^\/]+)\/([^\/]+)/); if (githubMatch) { const [, owner, repo] = githubMatch; // Clean up repo name (remove .git if present) const cleanRepo = repo.replace(".git", ""); // Construct the latest release asset download URL return `https://github.com/${owner}/${cleanRepo}/releases/latest/download/${releaseAssetId}`; } } catch (error) { console.error("\x1b[90m%s\x1b[0m", "Error processing github URL:", error); } } return ""; }; export const generateRelease = async () => { console.log("\x1b[33m%s\x1b[0m", "Reading package.json and manifest.json..."); const { packageJson, manifestJson } = loadConfigs(); // Calculate hash of the zip file console.log("\x1b[33m%s\x1b[0m", "Calculating package hash..."); const packageName = packageJson.name; const version = (manifestJson.version || packageJson.version).replaceAll( "v", "" ); const distPath = join(process.cwd(), "dist"); const zipPath = join(distPath, `${packageName}-v${version}.zip`); const iconPath = join(distPath, "icons", `${manifestJson.id}.svg`); const iconPathAlt = join(distPath, "images", `${manifestJson.id}.svg`); const iconFilePath = existsSync(iconPath) ? iconPath : existsSync(iconPathAlt) ? iconPathAlt : null; const icon = iconFilePath ? `data:image/svg+xml;base64,${readFileSync(iconFilePath, "base64")}` : ""; if (icon) { console.log( "\x1b[33m%s\x1b[0m", "Icon found, adding to release metadata..." ); } // Always prefer the provided updateUrl, but fallback to GitHub URLs generating a new one if it's not provided const updateUrl = getLatestReleasesFromGithubURLs( `${packageName}-v${version}.zip`, [manifestJson.repository, packageJson.repository] ); let fileHash = ""; let fileSize: number = -1; try { const fileBuffer = readFileSync(zipPath); const hashSum = createHash("sha512"); hashSum.update(fileBuffer); fileHash = hashSum.digest("hex"); fileSize = fileBuffer.length; } catch (err) { console.warn( "\x1b[33m%s\x1b[0m", "Could not generate hash for package file" ); } console.log("\x1b[33m%s\x1b[0m", "Generating release metadata..."); console.log("\x1b[33m%s\x1b[0m", "Validating Url..."); const isValidUrl = await validateRepoUrl(manifestJson.repository); if (isValidUrl) { console.log("\x1b[32m%s\x1b[0m", "✅ Url is valid"); } else { console.error("\x1b[31m%s\x1b[0m", "⚠️ Url is not valid! You may need to provide a valid GitHub repository URL in manifest.json. If you ignore, DeskThing will be unable to download your app"); } const release: ClientLatestJSONLatest = { meta_version: '0.11.8', meta_type: 'client', repository: manifestJson.repository || packageJson.repository?.url, icon: icon, clientManifest: manifestJson, updateUrl: updateUrl, hash: fileHash, hashAlgorithm: "sha512", size: fileSize, updatedAt: Date.now(), createdAt: Date.now(), downloads: 0 }; return release; }; export async function createReleaseFile() { console.log("\x1b[33m%s\x1b[0m", "Creating release file..."); try { await sanitizeClient(); const release = await generateRelease(); const releaseFilePath = await getReleaseFilePath(release.clientManifest.id); writeFileSync(releaseFilePath, JSON.stringify(release, null, 2)); console.log("\x1b[32m%s\x1b[0m", "Release file created successfully"); } catch (err) { console.error("\x1b[31m%s\x1b[0m", "Failed to create release file:", err); } }