chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
{
|
||||
"ffmpeg": {
|
||||
"repo": "eugeneware/ffmpeg-static",
|
||||
"version": "b6.0",
|
||||
"assets": {
|
||||
"darwin-x64": "ffmpeg-darwin-x64.gz",
|
||||
"darwin-arm64": "ffmpeg-darwin-arm64.gz",
|
||||
"linux-x64": "ffmpeg-linux-x64.gz",
|
||||
"linux-arm64": "ffmpeg-linux-arm64.gz",
|
||||
"win32-x64": "ffmpeg-win32-x64.gz"
|
||||
},
|
||||
"binaryName": {
|
||||
"default": "ffmpeg",
|
||||
"win32": "ffmpeg.exe"
|
||||
}
|
||||
},
|
||||
"N_m3u8DL-RE": {
|
||||
"repo": "nilaoda/N_m3u8DL-RE",
|
||||
"version": "v0.3.0-beta",
|
||||
"assets": {
|
||||
"darwin-x64": "N_m3u8DL-RE_v0.3.0-beta_osx-x64_20241203.tar.gz",
|
||||
"darwin-arm64": "N_m3u8DL-RE_v0.3.0-beta_osx-arm64_20241203.tar.gz",
|
||||
"linux-x64": "N_m3u8DL-RE_v0.3.0-beta_linux-x64_20241203.tar.gz",
|
||||
"linux-arm64": "N_m3u8DL-RE_v0.3.0-beta_linux-arm64_20241203.tar.gz",
|
||||
"win32-x64": "N_m3u8DL-RE_v0.3.0-beta_win-x64_20241203.zip",
|
||||
"win32-arm64": "N_m3u8DL-RE_v0.3.0-beta_win-arm64_20241203.zip"
|
||||
},
|
||||
"binaryName": {
|
||||
"default": "N_m3u8DL-RE",
|
||||
"win32": "N_m3u8DL-RE.exe"
|
||||
},
|
||||
"extractBinary": {
|
||||
"default": "N_m3u8DL-RE",
|
||||
"win32": "N_m3u8DL-RE.exe"
|
||||
}
|
||||
},
|
||||
"BBDown": {
|
||||
"repo": "nilaoda/BBDown",
|
||||
"version": "1.6.3",
|
||||
"assets": {
|
||||
"darwin-x64": "BBDown_1.6.3_20240814_osx-x64.zip",
|
||||
"darwin-arm64": "BBDown_1.6.3_20240814_osx-arm64.zip",
|
||||
"linux-x64": "BBDown_1.6.3_20240814_linux-x64.zip",
|
||||
"linux-arm64": "BBDown_1.6.3_20240814_linux-arm64.zip",
|
||||
"win32-x64": "BBDown_1.6.3_20240814_win-x64.zip",
|
||||
"win32-arm64": "BBDown_1.6.3_20240814_win-arm64.zip"
|
||||
},
|
||||
"binaryName": {
|
||||
"default": "BBDown",
|
||||
"win32": "BBDown.exe"
|
||||
},
|
||||
"extractBinary": {
|
||||
"default": "BBDown",
|
||||
"win32": "BBDown.exe"
|
||||
}
|
||||
},
|
||||
"aria2": {
|
||||
"source": "local",
|
||||
"path": "extra/aria2",
|
||||
"binaryName": {
|
||||
"default": "aria2c",
|
||||
"win32": "aria2c.exe"
|
||||
}
|
||||
},
|
||||
"yt-dlp": {
|
||||
"repo": "yt-dlp/yt-dlp",
|
||||
"version": "2026.03.17",
|
||||
"assets": {
|
||||
"darwin-x64": "yt-dlp_macos",
|
||||
"darwin-arm64": "yt-dlp_macos",
|
||||
"linux-x64": "yt-dlp_linux",
|
||||
"linux-arm64": "yt-dlp_linux_aarch64",
|
||||
"win32-x64": "yt-dlp.exe",
|
||||
"win32-arm64": "yt-dlp.exe"
|
||||
},
|
||||
"binaryName": {
|
||||
"default": "yt-dlp",
|
||||
"win32": "yt-dlp.exe"
|
||||
}
|
||||
},
|
||||
"mediago": {
|
||||
"repo": "caorushizi/mediago-core",
|
||||
"version": "v0.2.1",
|
||||
"assets": {
|
||||
"darwin-x64": "mediago-v0.2.1-darwin-amd64.tar.gz",
|
||||
"darwin-arm64": "mediago-v0.2.1-darwin-arm64.tar.gz",
|
||||
"linux-x64": "mediago-v0.2.1-linux-amd64.tar.gz",
|
||||
"linux-arm64": "mediago-v0.2.1-linux-arm64.tar.gz",
|
||||
"win32-x64": "mediago-v0.2.1-windows-amd64.zip",
|
||||
"win32-arm64": "mediago-v0.2.1-windows-arm64.zip"
|
||||
},
|
||||
"binaryName": {
|
||||
"default": "mediago",
|
||||
"win32": "mediago.exe"
|
||||
},
|
||||
"extractBinary": {
|
||||
"default": "mediago",
|
||||
"win32": "mediago.exe"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/bin/sh
|
||||
# MediaGo Docker entrypoint.
|
||||
#
|
||||
# `exec` replaces the shell with mediago-core so signals (SIGTERM on
|
||||
# `docker stop`) reach the Go process directly — no shell wrapper in the
|
||||
# middle that would swallow them. `"$@"` forwards any extra args passed
|
||||
# via `docker run ... mediago-core --foo=bar`, letting callers override
|
||||
# individual flags without replacing the whole command.
|
||||
set -e
|
||||
|
||||
exec mediago-core \
|
||||
--port=8899 \
|
||||
--static-dir=/app/static \
|
||||
--enable-auth \
|
||||
--db-path=/app/mediago/data/mediago.db \
|
||||
--config-dir=/app/mediago/data \
|
||||
--log-dir=/app/mediago/logs \
|
||||
--local-dir=/app/mediago/downloads \
|
||||
--deps-dir=/app/deps \
|
||||
"$@"
|
||||
@@ -0,0 +1,404 @@
|
||||
/**
|
||||
* download-deps.ts
|
||||
*
|
||||
* Provisions third-party tool binaries for the current (or all) platform(s).
|
||||
*
|
||||
* Two source types are supported:
|
||||
* - `source: "github"` (default) — fetch from a GitHub Release.
|
||||
* - `source: "local"` — copy from a repo-tracked directory (e.g. `extra/<tool>/`).
|
||||
* Used for tools we can't reliably fetch from a single upstream (aria2's
|
||||
* static builds are scattered across different repos per-platform), so we
|
||||
* vendor them in-tree instead.
|
||||
*
|
||||
* Tools: ffmpeg, N_m3u8DL-RE, BBDown, aria2, yt-dlp, mediago.
|
||||
*
|
||||
* Usage:
|
||||
* tsx scripts/download-deps.ts # Download for current platform only
|
||||
* tsx scripts/download-deps.ts --all # Download for all platforms
|
||||
*/
|
||||
|
||||
import {
|
||||
createWriteStream,
|
||||
createReadStream,
|
||||
existsSync,
|
||||
chmodSync,
|
||||
copyFileSync,
|
||||
mkdirSync,
|
||||
readFileSync,
|
||||
statSync,
|
||||
} from "node:fs";
|
||||
import { rename, unlink, readdir, rm } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { pipeline } from "node:stream/promises";
|
||||
import { createGunzip } from "node:zlib";
|
||||
import { execSync } from "node:child_process";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
// Load tool definitions
|
||||
const depsVersions = JSON.parse(
|
||||
readFileSync(path.join(__dirname, "deps-versions.json"), "utf-8"),
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// Types
|
||||
// ============================================================
|
||||
|
||||
interface ToolDef {
|
||||
/**
|
||||
* Where to fetch the binary from.
|
||||
* - "github" (default): download from a GitHub Release using `repo`, `version`, `assets`.
|
||||
* - "local": copy from a repo-tracked directory at `path/<os>/<arch>/<binaryName>`.
|
||||
*/
|
||||
source?: "github" | "local";
|
||||
/** Repo-relative directory holding vendored binaries. Required for `source: "local"`. */
|
||||
path?: string;
|
||||
/** GitHub repo in `owner/name` form. Required for `source: "github"`. */
|
||||
repo?: string;
|
||||
/** Release tag (e.g. `v1.6.5`). Required for `source: "github"`. */
|
||||
version?: string;
|
||||
/** Per-platform asset filename on the GitHub release. Required for `source: "github"`. */
|
||||
assets?: Record<string, string>;
|
||||
binaryName: { default: string; win32?: string };
|
||||
extractBinary?: { default: string; win32?: string };
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Platform helpers
|
||||
// ============================================================
|
||||
|
||||
const PLATFORM_MAP: Record<string, string> = {
|
||||
darwin: "darwin",
|
||||
linux: "linux",
|
||||
win32: "win32",
|
||||
};
|
||||
|
||||
const ARCH_MAP: Record<string, string> = {
|
||||
x64: "x64",
|
||||
arm64: "arm64",
|
||||
};
|
||||
|
||||
function getCurrentPlatformKey(): string {
|
||||
const platform = PLATFORM_MAP[process.platform];
|
||||
const arch = ARCH_MAP[process.arch];
|
||||
if (!platform || !arch) {
|
||||
throw new Error(
|
||||
`Unsupported platform: ${process.platform}-${process.arch}`,
|
||||
);
|
||||
}
|
||||
return `${platform}-${arch}`;
|
||||
}
|
||||
|
||||
function getAllPlatformKeys(): string[] {
|
||||
const keys: string[] = [];
|
||||
for (const p of Object.values(PLATFORM_MAP)) {
|
||||
for (const a of Object.values(ARCH_MAP)) {
|
||||
keys.push(`${p}-${a}`);
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
}
|
||||
|
||||
function getBinaryName(tool: ToolDef, platformKey: string): string {
|
||||
const isWin = platformKey.startsWith("win32");
|
||||
return isWin && tool.binaryName.win32
|
||||
? tool.binaryName.win32
|
||||
: tool.binaryName.default;
|
||||
}
|
||||
|
||||
function getExtractBinaryName(
|
||||
tool: ToolDef,
|
||||
platformKey: string,
|
||||
): string | undefined {
|
||||
if (!tool.extractBinary) return undefined;
|
||||
const isWin = platformKey.startsWith("win32");
|
||||
return isWin && tool.extractBinary.win32
|
||||
? tool.extractBinary.win32
|
||||
: tool.extractBinary.default;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Download and extraction
|
||||
// ============================================================
|
||||
|
||||
const DEPS_DIR = path.resolve(__dirname, "..", ".deps");
|
||||
|
||||
async function downloadFile(url: string, dest: string): Promise<void> {
|
||||
const response = await fetch(url, {
|
||||
redirect: "follow",
|
||||
headers: process.env.GITHUB_TOKEN
|
||||
? { Authorization: `token ${process.env.GITHUB_TOKEN}` }
|
||||
: {},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
`Failed to download ${url}: ${response.status} ${response.statusText}`,
|
||||
);
|
||||
}
|
||||
|
||||
const fileStream = createWriteStream(dest);
|
||||
// @ts-expect-error Node.js ReadableStream compatibility
|
||||
await pipeline(response.body, fileStream);
|
||||
}
|
||||
|
||||
async function extractGz(filePath: string, outputPath: string): Promise<void> {
|
||||
const gunzip = createGunzip();
|
||||
const source = createReadStream(filePath);
|
||||
const dest = createWriteStream(outputPath);
|
||||
await pipeline(source, gunzip, dest);
|
||||
}
|
||||
|
||||
async function extractZip(zipPath: string, outputDir: string): Promise<void> {
|
||||
if (process.platform === "win32") {
|
||||
const psCommand = `Add-Type -AssemblyName System.IO.Compression.FileSystem; if (Test-Path -LiteralPath '${outputDir}') { Remove-Item -LiteralPath '${outputDir}' -Recurse -Force }; [System.IO.Compression.ZipFile]::ExtractToDirectory('${zipPath}', '${outputDir}')`;
|
||||
execSync(`powershell -NoProfile -Command "${psCommand}"`, {
|
||||
stdio: "pipe",
|
||||
});
|
||||
} else {
|
||||
execSync(`unzip -o "${zipPath}" -d "${outputDir}"`, { stdio: "pipe" });
|
||||
}
|
||||
}
|
||||
|
||||
async function extractTarGz(
|
||||
tarGzPath: string,
|
||||
outputDir: string,
|
||||
): Promise<void> {
|
||||
execSync(`tar -xzf "${tarGzPath}" -C "${outputDir}"`, { stdio: "pipe" });
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a vendored (repo-tracked) binary from `<repoRoot>/<tool.path>/<os>/<arch>/<binaryName>`
|
||||
* into `.deps/<os>-<arch>/<binaryName>`. Used for tools whose per-platform
|
||||
* static builds live in the repo rather than upstream releases.
|
||||
*
|
||||
* The layout intentionally diverges from `.deps/`:
|
||||
* - source: `<tool.path>/<os>/<arch>/...` (two-level `os/arch`)
|
||||
* - dest: `.deps/<os>-<arch>/...` (flat `os-arch`)
|
||||
* which keeps the vendored tree navigable in a file browser while letting
|
||||
* binaryResolver.ts keep its single-directory-per-platform convention.
|
||||
*/
|
||||
function copyLocalTool(
|
||||
toolName: string,
|
||||
tool: ToolDef,
|
||||
platformKey: string,
|
||||
): void {
|
||||
if (!tool.path) {
|
||||
console.log(` ⚠ ${toolName} has source:"local" but no path; skipping`);
|
||||
return;
|
||||
}
|
||||
|
||||
const [os, arch] = platformKey.split("-");
|
||||
const binaryName = getBinaryName(tool, platformKey);
|
||||
const srcFile = path.resolve(
|
||||
__dirname,
|
||||
"..",
|
||||
tool.path,
|
||||
os,
|
||||
arch,
|
||||
binaryName,
|
||||
);
|
||||
const destDir = path.join(DEPS_DIR, platformKey);
|
||||
const destFile = path.join(destDir, binaryName);
|
||||
|
||||
if (!existsSync(srcFile)) {
|
||||
console.log(
|
||||
` ⚠ No vendored ${toolName} at ${path.relative(process.cwd(), srcFile)}, skipping`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip if destination already matches source (size-based heuristic —
|
||||
// cheap and catches the common case of "already provisioned once").
|
||||
if (existsSync(destFile)) {
|
||||
const srcSize = statSync(srcFile).size;
|
||||
const destSize = statSync(destFile).size;
|
||||
if (srcSize === destSize) {
|
||||
console.log(` ✓ ${toolName} already exists for ${platformKey}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mkdirSync(destDir, { recursive: true });
|
||||
copyFileSync(srcFile, destFile);
|
||||
|
||||
if (!platformKey.startsWith("win32")) {
|
||||
try {
|
||||
chmodSync(destFile, 0o755);
|
||||
} catch {
|
||||
// Ignore permission errors on Windows host
|
||||
}
|
||||
}
|
||||
|
||||
console.log(` ✓ ${toolName} ready for ${platformKey} (local)`);
|
||||
}
|
||||
|
||||
async function downloadTool(
|
||||
toolName: string,
|
||||
tool: ToolDef,
|
||||
platformKey: string,
|
||||
): Promise<void> {
|
||||
// Vendored tools: bypass the GitHub release path entirely.
|
||||
if (tool.source === "local") {
|
||||
copyLocalTool(toolName, tool, platformKey);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!tool.assets) {
|
||||
console.log(` ⚠ ${toolName} has no assets defined; skipping`);
|
||||
return;
|
||||
}
|
||||
const assetName = tool.assets[platformKey];
|
||||
if (!assetName) {
|
||||
console.log(` ⚠ No asset for ${toolName} on ${platformKey}, skipping`);
|
||||
return;
|
||||
}
|
||||
if (!tool.repo || !tool.version) {
|
||||
console.log(` ⚠ ${toolName} missing repo/version; skipping`);
|
||||
return;
|
||||
}
|
||||
|
||||
const destDir = path.join(DEPS_DIR, platformKey);
|
||||
mkdirSync(destDir, { recursive: true });
|
||||
|
||||
const binaryName = getBinaryName(tool, platformKey);
|
||||
const binaryPath = path.join(destDir, binaryName);
|
||||
|
||||
// Skip if already downloaded
|
||||
if (existsSync(binaryPath)) {
|
||||
console.log(` ✓ ${toolName} already exists for ${platformKey}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const url = `https://github.com/${tool.repo}/releases/download/${tool.version}/${assetName}`;
|
||||
const tempFile = path.join(destDir, assetName);
|
||||
|
||||
console.log(` ↓ Downloading ${toolName} for ${platformKey}...`);
|
||||
await downloadFile(url, tempFile);
|
||||
|
||||
// Extract based on file type
|
||||
const extractBinaryName = getExtractBinaryName(tool, platformKey);
|
||||
|
||||
if (assetName.endsWith(".gz") && !assetName.endsWith(".tar.gz")) {
|
||||
// Simple gzip (e.g., ffmpeg-static)
|
||||
await extractGz(tempFile, binaryPath);
|
||||
await unlink(tempFile);
|
||||
} else if (assetName.endsWith(".tar.gz")) {
|
||||
// tar.gz archive
|
||||
const extractDir = path.join(destDir, `_extract_${toolName}`);
|
||||
mkdirSync(extractDir, { recursive: true });
|
||||
await extractTarGz(tempFile, extractDir);
|
||||
|
||||
// Find the binary in extracted directory
|
||||
const found = await findBinaryInDir(
|
||||
extractDir,
|
||||
extractBinaryName || binaryName,
|
||||
);
|
||||
if (found) {
|
||||
await rename(found, binaryPath);
|
||||
} else {
|
||||
throw new Error(
|
||||
`Could not find ${extractBinaryName || binaryName} in extracted archive`,
|
||||
);
|
||||
}
|
||||
|
||||
await rm(extractDir, { recursive: true, force: true });
|
||||
await unlink(tempFile);
|
||||
} else if (assetName.endsWith(".zip")) {
|
||||
// zip archive
|
||||
const extractDir = path.join(destDir, `_extract_${toolName}`);
|
||||
mkdirSync(extractDir, { recursive: true });
|
||||
await extractZip(tempFile, extractDir);
|
||||
|
||||
// Find the binary in extracted directory
|
||||
const found = await findBinaryInDir(
|
||||
extractDir,
|
||||
extractBinaryName || binaryName,
|
||||
);
|
||||
if (found) {
|
||||
await rename(found, binaryPath);
|
||||
} else {
|
||||
throw new Error(
|
||||
`Could not find ${extractBinaryName || binaryName} in extracted archive`,
|
||||
);
|
||||
}
|
||||
|
||||
await rm(extractDir, { recursive: true, force: true });
|
||||
await unlink(tempFile);
|
||||
} else {
|
||||
// Direct binary
|
||||
await rename(tempFile, binaryPath);
|
||||
}
|
||||
|
||||
// Set executable permission on non-Windows
|
||||
if (!platformKey.startsWith("win32")) {
|
||||
try {
|
||||
chmodSync(binaryPath, 0o755);
|
||||
} catch {
|
||||
// Ignore permission errors on Windows host
|
||||
}
|
||||
}
|
||||
|
||||
console.log(` ✓ ${toolName} ready for ${platformKey}`);
|
||||
}
|
||||
|
||||
async function findBinaryInDir(
|
||||
dir: string,
|
||||
name: string,
|
||||
): Promise<string | null> {
|
||||
const entries = await readdir(dir, { withFileTypes: true, recursive: true });
|
||||
for (const entry of entries) {
|
||||
if (entry.isFile() && entry.name === name) {
|
||||
return path.join(entry.parentPath || dir, entry.name);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Main
|
||||
// ============================================================
|
||||
|
||||
async function main() {
|
||||
const isAll = process.argv.includes("--all");
|
||||
const platformIdx = process.argv.indexOf("--platform");
|
||||
const explicitPlatform =
|
||||
platformIdx !== -1 ? process.argv[platformIdx + 1] : undefined;
|
||||
|
||||
let platforms: string[];
|
||||
if (isAll) {
|
||||
platforms = getAllPlatformKeys();
|
||||
} else if (explicitPlatform) {
|
||||
platforms = [explicitPlatform];
|
||||
} else {
|
||||
platforms = [getCurrentPlatformKey()];
|
||||
}
|
||||
|
||||
console.log(
|
||||
`Downloading third-party tools for ${isAll ? "all platforms" : platforms[0]}...`,
|
||||
);
|
||||
|
||||
const tools = depsVersions as Record<string, ToolDef>;
|
||||
|
||||
for (const platformKey of platforms) {
|
||||
console.log(`\n📦 Platform: ${platformKey}`);
|
||||
for (const [toolName, tool] of Object.entries(tools)) {
|
||||
try {
|
||||
await downloadTool(toolName, tool, platformKey);
|
||||
} catch (err) {
|
||||
console.error(
|
||||
` ✗ Failed to download ${toolName} for ${platformKey}: ${err}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log("\n✅ Done!");
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Fatal error:", err);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Zip the built Chromium extension into `release/` so the user can
|
||||
* share a single file. Matches the cross-platform pattern in
|
||||
* `scripts/download-deps.ts` (PowerShell on Windows, `zip` on Unix).
|
||||
*
|
||||
* Run via:
|
||||
* pnpm build:extension
|
||||
* tsx scripts/pack-extension.ts
|
||||
* (or `pnpm pack:extension` which chains both).
|
||||
*/
|
||||
|
||||
import { execSync } from "node:child_process";
|
||||
import { existsSync, mkdirSync, readFileSync, rmSync } from "node:fs";
|
||||
import { dirname, join, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const root = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const extDir = join(root, "packages", "mediago-extension");
|
||||
const distDir = join(extDir, "dist");
|
||||
const releaseDir = join(root, "release");
|
||||
|
||||
interface PkgJson {
|
||||
version?: string;
|
||||
}
|
||||
|
||||
function readVersion(): string {
|
||||
const pkg = JSON.parse(
|
||||
readFileSync(join(extDir, "package.json"), "utf8"),
|
||||
) as PkgJson;
|
||||
return pkg.version ?? "0.0.0";
|
||||
}
|
||||
|
||||
function zipDirectory(sourceDir: string, outputZip: string): void {
|
||||
// Make sure any stale zip at the target path is gone — Windows'
|
||||
// Compress-Archive refuses to overwrite silently.
|
||||
if (existsSync(outputZip)) rmSync(outputZip);
|
||||
|
||||
if (process.platform === "win32") {
|
||||
const ps = `Compress-Archive -Path '${sourceDir}\\*' -DestinationPath '${outputZip}' -Force`;
|
||||
execSync(`powershell -NoProfile -Command "${ps}"`, { stdio: "inherit" });
|
||||
} else {
|
||||
// -r recursive, run inside sourceDir so paths are relative, use -q
|
||||
// to silence per-file output.
|
||||
execSync(`cd "${sourceDir}" && zip -r -q "${outputZip}" .`, {
|
||||
stdio: "inherit",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function main(): void {
|
||||
if (!existsSync(distDir)) {
|
||||
console.error(
|
||||
`[pack-extension] ${distDir} does not exist. Run \`pnpm build:extension\` first.`,
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
mkdirSync(releaseDir, { recursive: true });
|
||||
|
||||
const version = readVersion();
|
||||
const outputZip = join(releaseDir, `mediago-extension-v${version}.zip`);
|
||||
|
||||
console.log(`[pack-extension] zipping ${distDir} → ${outputZip}`);
|
||||
zipDirectory(distDir, outputZip);
|
||||
console.log(`[pack-extension] ✓ created ${outputZip}`);
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user