[READ-ONLY] Mirror of https://github.com/andrioid/md-social. markdown social media poster (experimental)
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162/** * @fileoverview Binary fetcher for md-social from GitHub releases * Node 18+ * Env: OWNER, REPO, VERSION (or "latest"), ASSET (optional), GITHUB_TOKEN (optional) */import { createWriteStream } from "node:fs";import { chmod, mkdir, readFile } from "node:fs/promises";import path from "node:path/win32";import { Readable } from "node:stream";import { pipeline } from "node:stream/promises";import { promisify } from "node:util";import zlib from "node:zlib";
/** @type {(source: NodeJS.ReadableStream, destination: NodeJS.WritableStream) => Promise<void>} */const streamPipeline = promisify(pipeline);
/** @type {string} */const base = `md-social-${getPlatform()}-${getArch()}`;
/** @type {{ version?: string }} */const pkgJson = JSON.parse(await readFile("package.json", "utf8"));
/** @type {string} */const toolname = "md-social";
/** @type {string} */const OWNER = "andrioid";/** @type {string} */const REPO = "md-social";/** @type {string} */const VERSION = `v${pkgJson.version}` || "latest";
// Try common filename variants. No predefined support list./** @type {string[]} */const candidates = [ base, `${base}.gz`, // Executable suffix on Windows is a common gotcha: process.platform === "win32" ? `${base}.exe.zip` : null, `${base}.zip`,].filter((v) => v !== null);
/** @type {string} */const prefix = VERSION === "latest" ? `https://github.com/${OWNER}/${REPO}/releases/latest/download/` : `https://github.com/${OWNER}/${REPO}/releases/download/${VERSION}/`;
const outDir = new URL("bin/", import.meta.url);await mkdir(outDir, { recursive: true });const outPath = new URL(`bin/${toolname}`, import.meta.url);
/** @type {Record<string, string>} */const headers = process.env.GITHUB_TOKEN ? { Authorization: `Bearer ${process.env.GITHUB_TOKEN}` } : {};
/** @type {boolean} */let downloaded = false;for (const name of candidates) { downloaded = await downloadAndDecompress(name); if (downloaded) break;}
if (!downloaded) { console.error(`Could not download any of: ${candidates.join(", ")} from ${prefix}`); // Let install fail (your requirement). process.exit(1);}
/** * Maps Node.js process.arch to Go architecture names * @returns {string} The architecture string for the binary */function getArch() { const arch = process.arch; switch (arch) { case "x64": return "amd64"; case "arm64": return "arm64"; case "arm": return "arm"; // may want to detect armv6 vs armv7 case "ia32": return "386"; case "ppc64": return "ppc64"; case "s390x": return "s390x"; case "riscv64": return "riscv64"; default: return arch; // passthrough if unknown }}
/** * Maps Node.js process.platform to Go platform names * @returns {string} The platform string for the binary */function getPlatform() { const platform = process.platform; switch (platform) { case "darwin": return "darwin"; case "linux": return "linux"; case "win32": return "windows"; default: return platform; // passthrough if unknown }}
/** * Uncompress the file, using the appropriate tool * @param {string} ext The source file path */function getUncompressor(ext) { // get file extension let handler = null;
switch (ext) { case ".gz": handler = zlib.createGunzip(); case ".zip": handler = zlib.createUnzip(); break; default: throw new Error(`Unsupported compression format: ${ext}`); }
return handler;}
/** * * @param {string} name * @returns {Promise<boolean>} If we successfully downloaded */async function downloadAndDecompress(name) { const url = prefix + encodeURIComponent(name); const res = await fetch(url, { headers }); if (!res.ok) { // 404/403/etc.—try next candidate return false; } if (!res.body) return false; // Create a stream from res.body // @ts-ignore naughty types from node.js const srcStream = Readable.fromWeb(res.body); // extension from filename const ext = path.extname(name); const uncompressor = getUncompressor(ext);
const dstPath = new URL(`bin/md-social`, import.meta.url); const dstStream = createWriteStream(dstPath); await pipeline(srcStream, uncompressor, dstStream); dstStream.close();
// Setting permissions if (process.platform !== "win32") await chmod(outPath, 0o755); console.log(`Downloaded ${name} -> ${outPath.pathname}`); return true;}