Source identity
| Field | Recorded value |
|---|---|
| Source type | GitHub source |
| Original record | Janady13/thatdeveloperguy-website / scripts/install-rive-cli.mjs |
| Date | Not specified in source |
| Repository | Janady13/thatdeveloperguy-website |
| Revision | 2bea2ebdff0e34494bff597d4fa9c8422a0c3a94 |
| Branch | main |
| Path or archive member | scripts/install-rive-cli.mjs |
| Original SHA-256 | 6a5ee4180ed0e635730525bba5eb1b6f585077cbeecc1adfa88b353d461b324c |
| Git blob SHA | ffbe9d5cef55c5e8ae3cd4a7eb56aa06326c97ff |
| Reading-copy SHA-256 | 6a5ee4180ed0e635730525bba5eb1b6f585077cbeecc1adfa88b353d461b324c |
Recovered source transcript
Download complete source text ↓27 lines · 2.6 KB
/** Install the official Rive CLI (checksum-verified from releases.rive.app) into .tools/rive without running any installer script. */
import { createHash } from 'node:crypto';
import { mkdtempSync, writeFileSync, mkdirSync, copyFileSync, chmodSync, lstatSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
import { spawnSync } from 'node:child_process';
const root = fileURLToPath(new URL('..', import.meta.url));
const version = process.env.RIVE_CLI_VERSION ?? '1.0.3', base = 'https://releases.rive.app/cli';
const platform = process.platform === 'darwin' && process.arch === 'arm64' ? 'darwin-arm64' : process.platform === 'linux' && process.arch === 'x64' ? 'linux-x64' : null;
if (!platform) throw new Error('supported: macOS arm64, Linux x64');
const get = async url => { const r = await fetch(url, { signal: AbortSignal.timeout(120000) }); if (!r.ok) throw new Error(`${r.status} ${url}`); return r; };
const manifest = await (await get(`${base}/v${version}/manifest.json`)).json();
const artifact = manifest.artifacts?.[platform];
if (manifest.version !== version || !artifact || !/^[a-f0-9]{64}$/.test(artifact.sha256)) throw new Error('unexpected manifest');
const bytes = Buffer.from(await (await get(`${base}/${artifact.path}`)).arrayBuffer());
const sha = createHash('sha256').update(bytes).digest('hex');
if (sha !== artifact.sha256) throw new Error('checksum mismatch');
const temp = mkdtempSync(resolve(tmpdir(), 'tdg-rive-')), archive = resolve(temp, 'rive.tar.gz'); writeFileSync(archive, bytes);
const list = spawnSync('tar', ['-tzf', archive], { encoding: 'utf8' }); if (list.status !== 0 || list.stdout.split('\n').some(p => p.startsWith('/') || p.split('/').includes('..'))) throw new Error('unsafe archive');
const unpack = spawnSync('tar', ['-xzf', archive, '-C', temp], { encoding: 'utf8' }); if (unpack.status !== 0) throw new Error(unpack.stderr);
const binary = resolve(temp, 'rive'); if (!lstatSync(binary).isFile()) throw new Error('no rive binary in archive');
const out = resolve(root, '.tools/rive'); mkdirSync(out, { recursive: true }); copyFileSync(binary, resolve(out, 'rive')); chmodSync(resolve(out, 'rive'), 0o755);
mkdirSync(resolve(root, 'evidence'), { recursive: true });
writeFileSync(resolve(root, 'evidence/rive-cli-provenance.json'), JSON.stringify({ version, platform, url: `${base}/${artifact.path}`, sha256: sha, installedAt: new Date().toISOString() }, null, 2) + '\n');
console.log(`official Rive CLI ${version} (${platform}) sha256 ${sha.slice(0, 12)}… → ${resolve(out, 'rive')}`);