convert-clash-meta-mrs.ts 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. import path from 'path';
  2. import fs from 'fs';
  3. import fsp from 'fs/promises';
  4. import { Readable } from 'stream';
  5. import { pipeline } from 'stream/promises';
  6. import zlib from 'zlib';
  7. import { async as ezspawn } from '@jsdevtools/ez-spawn';
  8. const mihomoBinaryDir = path.join(__dirname, '../../node_modules/.cache/mihomo');
  9. const mihomoBinaryPath = path.join(mihomoBinaryDir, 'mihomo');
  10. const mihomoBinaryUrl: Partial<Record<NodeJS.Platform, Partial<Record<NodeJS.Architecture, string>>>> = {
  11. linux: {
  12. x64: 'https://github.com/MetaCubeX/mihomo/releases/download/v1.18.7/mihomo-linux-amd64-compatible-v1.18.7.gz'
  13. },
  14. darwin: {
  15. x64: 'https://github.com/MetaCubeX/mihomo/releases/download/v1.18.7/mihomo-darwin-amd64-v1.18.7.gz',
  16. arm64: 'https://github.com/MetaCubeX/mihomo/releases/download/v1.18.7/mihomo-darwin-arm64-v1.18.7.gz'
  17. }
  18. };
  19. const ensureMihomoBinary = async () => {
  20. await fsp.mkdir(mihomoBinaryDir, { recursive: true });
  21. if (!fs.existsSync(mihomoBinaryPath)) {
  22. const writeStream = fs.createWriteStream(mihomoBinaryPath);
  23. const downloadUrl = mihomoBinaryUrl[process.platform]?.[process.arch];
  24. if (!downloadUrl) {
  25. throw new Error(`Unsupported platform: ${process.platform} ${process.arch}`);
  26. }
  27. const res = await fetch(downloadUrl);
  28. if (!res.ok || !res.body) {
  29. throw new Error(`Failed to download mihomo binary: ${res.statusText}`);
  30. }
  31. const gunzip = zlib.createGunzip();
  32. await pipeline(
  33. Readable.fromWeb(res.body),
  34. gunzip,
  35. writeStream
  36. );
  37. }
  38. await fsp.chmod(mihomoBinaryPath, 0o755);
  39. };
  40. export const convertClashMetaMrs = async (type: 'domain', format: 'text', input: string, output: string) => {
  41. await ensureMihomoBinary();
  42. const { stderr } = await ezspawn(mihomoBinaryPath, ['convert-ruleset', type, format, input, output]);
  43. if (stderr) {
  44. throw new Error(stderr);
  45. }
  46. };