diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..a2f7bfd --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,34 @@ +name: Build and Release + +on: + push: + tags: + - "*" + workflow_dispatch: + +permissions: + contents: write + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v5 + with: + fetch-depth: 0 + - name: Setup Node + uses: actions/setup-node@v6 + with: + node-version: latest + - name: Build + run: | + npm install + npm run compile + git log $(git describe --tags --abbrev=0 HEAD~1)..HEAD --oneline > changelog.txt + - name: Release + uses: softprops/action-gh-release@v2 + with: + make_latest: true + body_path: changelog.txt + files: bin/*/* diff --git a/.gitignore b/.gitignore index 9e87c05..a8cd699 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ node_modules -bin \ No newline at end of file +bin +.env +modpack.zip +test \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index bdb4c13..50cf215 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,16 +5,20 @@ "packages": { "": { "dependencies": { - "bun": "^1.3.3" + "commander": "^14.0.2", + "confbox": "^0.2.2", + "deno": "^2.5.6", + "dotenv": "^17.2.3", + "packwiz-extras-lib": "https://github.com/sugoidogo/packwiz-extras-lib/releases/download/2.1.0/packwiz-extras-lib.tgz" }, "devDependencies": { "@types/node": "^24.10.1" } }, - "node_modules/@oven/bun-darwin-aarch64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@oven/bun-darwin-aarch64/-/bun-darwin-aarch64-1.3.3.tgz", - "integrity": "sha512-eJopQrUk0WR7jViYDC29+Rp50xGvs4GtWOXBeqCoFMzutkkO3CZvHehA4JqnjfWMTSS8toqvRhCSOpOz62Wf9w==", + "node_modules/@deno/darwin-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@deno/darwin-arm64/-/darwin-arm64-2.5.6.tgz", + "integrity": "sha512-aQoAQSQdA8PVhS9ibx/vl1xtP0ngiZCD2tW/PqUd13fmwM12m3O2V8/oyMTzqXZtT/PnoiOtcqtujbF/yRUyVg==", "cpu": [ "arm64" ], @@ -24,10 +28,10 @@ "darwin" ] }, - "node_modules/@oven/bun-darwin-x64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64/-/bun-darwin-x64-1.3.3.tgz", - "integrity": "sha512-xGDePueVFrNgkS+iN0QdEFeRrx2MQ5hQ9ipRFu7N73rgoSSJsFlOKKt2uGZzunczedViIfjYl0ii0K4E9aZ0Ow==", + "node_modules/@deno/darwin-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@deno/darwin-x64/-/darwin-x64-2.5.6.tgz", + "integrity": "sha512-9GrCi8ga5mgYB1b/8Pj9vRF4VVNLTuzyVd6bL0vEKFBZ/w27cQj0oY2o60t8AUTpW8iXpJfXMDoY7j4yiK1Xug==", "cpu": [ "x64" ], @@ -37,23 +41,10 @@ "darwin" ] }, - "node_modules/@oven/bun-darwin-x64-baseline": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@oven/bun-darwin-x64-baseline/-/bun-darwin-x64-baseline-1.3.3.tgz", - "integrity": "sha512-1ij4wQ9ECLFf1XFry+IFUN+28if40ozDqq6+QtuyOhIwraKzXOlAUbILhRMGvM3ED3yBex2mTwlKpA4Vja/V2g==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@oven/bun-linux-aarch64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@oven/bun-linux-aarch64/-/bun-linux-aarch64-1.3.3.tgz", - "integrity": "sha512-DabZ3Mt1XcJneWdEEug8l7bCPVvDBRBpjUIpNnRnMFWFnzr8KBEpMcaWTwYOghjXyJdhB4MPKb19MwqyQ+FHAw==", + "node_modules/@deno/linux-arm64-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@deno/linux-arm64-glibc/-/linux-arm64-glibc-2.5.6.tgz", + "integrity": "sha512-HiAHeFBmNRsJFulNMQ2LX3k+IvAIhGAo9JcW/0PwrNa3WbMql9wq37pOPp8DkW2VUTvghh3FZm6GUcryUml4bQ==", "cpu": [ "arm64" ], @@ -63,88 +54,36 @@ "linux" ] }, - "node_modules/@oven/bun-linux-aarch64-musl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@oven/bun-linux-aarch64-musl/-/bun-linux-aarch64-musl-1.3.3.tgz", - "integrity": "sha512-XWQ3tV/gtZj0wn2AdSUq/tEOKWT4OY+Uww70EbODgrrq00jxuTfq5nnYP6rkLD0M/T5BHJdQRSfQYdIni9vldw==", + "node_modules/@deno/linux-x64-glibc": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@deno/linux-x64-glibc/-/linux-x64-glibc-2.5.6.tgz", + "integrity": "sha512-aYct9Vp1RgKR2yW9hyWGTIL0EN0MgqaBuD0fbnQHygd4ftSfd/aWcBB3+n7OTUX/YNWSxYkOMLV1N8RWUCj4jw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@deno/win32-arm64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@deno/win32-arm64/-/win32-arm64-2.5.6.tgz", + "integrity": "sha512-HZq7gShjAehx1d2qg2cHRJJbxpbBk8kVmoPiZpILnN66XRwbNlWtrAUwsXNyHuBHcaT+7LgPTRUzX3KuDYXbwg==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oven/bun-linux-x64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64/-/bun-linux-x64-1.3.3.tgz", - "integrity": "sha512-7eIARtKZKZDtah1aCpQUj/1/zT/zHRR063J6oAxZP9AuA547j5B9OM2D/vi/F4En7Gjk9FPjgPGTSYeqpQDzJw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oven/bun-linux-x64-baseline": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-baseline/-/bun-linux-x64-baseline-1.3.3.tgz", - "integrity": "sha512-IU8pxhIf845psOv55LqJyL+tSUc6HHMfs6FGhuJcAnyi92j+B1HjOhnFQh9MW4vjoo7do5F8AerXlvk59RGH2w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oven/bun-linux-x64-musl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-musl/-/bun-linux-x64-musl-1.3.3.tgz", - "integrity": "sha512-xNSDRPn1yyObKteS8fyQogwsS4eCECswHHgaKM+/d4wy/omZQrXn8ZyGm/ZF9B73UfQytUfbhE7nEnrFq03f0w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oven/bun-linux-x64-musl-baseline": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@oven/bun-linux-x64-musl-baseline/-/bun-linux-x64-musl-baseline-1.3.3.tgz", - "integrity": "sha512-JoRTPdAXRkNYouUlJqEncMWUKn/3DiWP03A7weBbtbsKr787gcdNna2YeyQKCb1lIXE4v1k18RM3gaOpQobGIQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@oven/bun-windows-x64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@oven/bun-windows-x64/-/bun-windows-x64-1.3.3.tgz", - "integrity": "sha512-kWqa1LKvDdAIzyfHxo3zGz3HFWbFHDlrNK77hKjUN42ycikvZJ+SHSX76+1OW4G8wmLETX4Jj+4BM1y01DQRIQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, "os": [ "win32" ] }, - "node_modules/@oven/bun-windows-x64-baseline": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@oven/bun-windows-x64-baseline/-/bun-windows-x64-baseline-1.3.3.tgz", - "integrity": "sha512-u5eZHKq6TPJSE282KyBOicGQ2trkFml0RoUfqkPOJVo7TXGrsGYYzdsugZRnVQY/WEmnxGtBy4T3PAaPqgQViA==", + "node_modules/@deno/win32-x64": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/@deno/win32-x64/-/win32-x64-2.5.6.tgz", + "integrity": "sha512-GRBl8+CQbNeTp9CrxbCuAuqxi592NZfac1AvDgFEPt8O9aZe/2k+y7AQwESJGxEvyJl1vw6UV24qdf9N7pCM9Q==", "cpu": [ "x64" ], @@ -164,37 +103,66 @@ "undici-types": "~7.16.0" } }, - "node_modules/bun": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/bun/-/bun-1.3.3.tgz", - "integrity": "sha512-2hJ4ocTZ634/Ptph4lysvO+LbbRZq8fzRvMwX0/CqaLBxrF2UB5D1LdMB8qGcdtCer4/VR9Bx5ORub0yn+yzmw==", - "cpu": [ - "arm64", - "x64" - ], + "node_modules/commander": { + "version": "14.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.2.tgz", + "integrity": "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==", + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/confbox": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz", + "integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==", + "license": "MIT" + }, + "node_modules/deno": { + "version": "2.5.6", + "resolved": "https://registry.npmjs.org/deno/-/deno-2.5.6.tgz", + "integrity": "sha512-SSe2gCf41A/uln54H7xdKZFtiDt+reBxYM4IaJLRH/NpEIE5T3VOcLSLHPaJzyiTvZe2xMz1QFcpg4cco5rNsA==", "hasInstallScript": true, "license": "MIT", - "os": [ - "darwin", - "linux", - "win32" - ], "bin": { - "bun": "bin/bun.exe", - "bunx": "bin/bunx.exe" + "deno": "bin.cjs" }, "optionalDependencies": { - "@oven/bun-darwin-aarch64": "1.3.3", - "@oven/bun-darwin-x64": "1.3.3", - "@oven/bun-darwin-x64-baseline": "1.3.3", - "@oven/bun-linux-aarch64": "1.3.3", - "@oven/bun-linux-aarch64-musl": "1.3.3", - "@oven/bun-linux-x64": "1.3.3", - "@oven/bun-linux-x64-baseline": "1.3.3", - "@oven/bun-linux-x64-musl": "1.3.3", - "@oven/bun-linux-x64-musl-baseline": "1.3.3", - "@oven/bun-windows-x64": "1.3.3", - "@oven/bun-windows-x64-baseline": "1.3.3" + "@deno/darwin-arm64": "2.5.6", + "@deno/darwin-x64": "2.5.6", + "@deno/linux-arm64-glibc": "2.5.6", + "@deno/linux-x64-glibc": "2.5.6", + "@deno/win32-arm64": "2.5.6", + "@deno/win32-x64": "2.5.6" + } + }, + "node_modules/dotenv": { + "version": "17.2.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", + "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/murmur2": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/murmur2/-/murmur2-1.0.2.tgz", + "integrity": "sha512-r9dVsfnmykIYovQH9oP2JeZu5/DYa9rZpSQw2FWR/VDoI0oxm/u21NF46bFH5h+x2Xv4q5+jHzsX95N6m0UO3Q==", + "license": "MIT" + }, + "node_modules/packwiz-extras-lib": { + "version": "2.1.0", + "resolved": "https://github.com/sugoidogo/packwiz-extras-lib/releases/download/2.1.0/packwiz-extras-lib.tgz", + "integrity": "sha512-mnP3x9TB/wN4a5Zs1l8pOBaBlr2B2spwHBdQ2vwrH+dMpzNb4Y/7LkzaBdQe8euQjBe2E9SmTyu71CPevmgeQQ==", + "license": "LGPL-3.0-or-later", + "dependencies": { + "confbox": "^0.2.2", + "murmur2": "^1.0.2", + "workerless": "https://github.com/sugoidogo/workerless/releases/download/0.1.0/workerless.tgz" } }, "node_modules/undici-types": { @@ -203,6 +171,21 @@ "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", "dev": true, "license": "MIT" + }, + "node_modules/web-worker": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.5.0.tgz", + "integrity": "sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==", + "license": "Apache-2.0" + }, + "node_modules/workerless": { + "version": "0.1.0", + "resolved": "https://github.com/sugoidogo/workerless/releases/download/0.1.0/workerless.tgz", + "integrity": "sha512-4fvxu+smJWC9QBYSblhv1HXOsHFopFa7D9SX4wfZv/FIUBIqbpHShooBT0PoKvtCdp68GF/ALrQ6yP32rTv5FQ==", + "license": "LGPL-3.0-or-later", + "dependencies": { + "web-worker": "^1.5.0" + } } } } diff --git a/package.json b/package.json index e722237..68b2682 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,17 @@ { + "type": "module", + "scripts": { + "test": "node scripts/test.ts", + "compile": "node scripts/compile.ts" + }, "devDependencies": { "@types/node": "^24.10.1" }, "dependencies": { - "bun": "^1.3.3" + "commander": "^14.0.2", + "confbox": "^0.2.2", + "deno": "^2.5.6", + "dotenv": "^17.2.3", + "packwiz-extras-lib": "https://github.com/sugoidogo/packwiz-extras-lib/releases/download/2.1.0/packwiz-extras-lib.tgz" } } diff --git a/scripts/compile.ts b/scripts/compile.ts new file mode 100644 index 0000000..d44db2a --- /dev/null +++ b/scripts/compile.ts @@ -0,0 +1,62 @@ +import spawnSync from "./spawnSync.ts" + +const deno = true // works, but produces largest executables +const bun = false // has weird issues +const pkg = false // smallest executables but don't work + +if (deno) { + //spawnSync('deno', ['install'], { stdio: 'inherit', shell: true }) + const deno_targets = [ + 'x86_64-apple-darwin', + 'aarch64-apple-darwin', + 'x86_64-pc-windows-msvc', + 'x86_64-unknown-linux-gnu', + 'aarch64-unknown-linux-gnu' + ] + for (const target of deno_targets) { + spawnSync('deno', [ + 'compile', '--allow-all', '--target', target, + '--output', 'bin/deno/packwiz-extras-' + target, + '--no-check', 'src/cli.ts' + ], { stdio: 'inherit', shell: true }) + } +} + +if (bun) { + const bun_targets = [ + 'bun-linux-x64-baseline', + 'bun-linux-arm64', + 'bun-linux-x64-musl-baseline', + 'bun-linux-arm64-musl', + 'bun-windows-x64-baseline', + 'bun-darwin-x64-baseline', + 'bun-darwin-arm64' + ] + for (const target of bun_targets) { + spawnSync('bun', [ + 'build', '--compile', + '--target', target, + '--outfile', 'bin/bun/packwiz-extras-' + target, + 'src/cli.ts' + ], { stdio: 'inherit', shell: true }) + } +} + +if (pkg) { + const pkg_targets = [ + 'latest-linux-x64', + 'latest-linux-arm64', + 'latest-windows-x64', + 'latest-macos-x64', + 'latest-macos-arm64' + ] + spawnSync('pkg', [ + '--targets', pkg_targets.join(','), + '--output', 'bin/pkg/packwiz-extras', + '--no-bytecode', '--public', // doesn't build without these + //'--sea', // doesn't build with this + '--compress', 'GZip', + //'--compress', 'Brotli', // same size as GZip and the internet says GZip is better + 'src/cli.ts' + ], { stdio: 'inherit', shell: true }) +} \ No newline at end of file diff --git a/scripts/downloadProgress.ts b/scripts/downloadProgress.ts new file mode 100644 index 0000000..ba69637 --- /dev/null +++ b/scripts/downloadProgress.ts @@ -0,0 +1,32 @@ +import fs from 'node:fs' + +export default async function download(url: string, path: string) { + if (fs.existsSync(path)) { + return console.log(path + ' already downloaded') + } + console.log('downloading ' + url + ' to ' + path) + const response = await fetch(url) + if (!response.ok) { + console.error(response.statusText) + process.exit(1) + } + const reader = response.body?.getReader() + const writeStream = fs.createWriteStream(path, 'binary') + const totalSize = Number(response.headers.get('content-length')) + let receivedSize = 0 + let chunk = await reader!.read() + let lastProgress = 0 + while (!chunk.done) { + writeStream.write(chunk.value) + receivedSize += chunk.value!.length + const progress = Math.floor((receivedSize / totalSize) * 100) + if (process.stdout.isTTY) process.stdout.write(progress + '%\r') + else if (progress !== lastProgress) { + process.stdout.write('.') + lastProgress = progress + } + chunk = await reader!.read() + } + process.stdout.write('\n') + writeStream.close() +} \ No newline at end of file diff --git a/scripts/spawnSync.ts b/scripts/spawnSync.ts new file mode 100644 index 0000000..d8a3ca0 --- /dev/null +++ b/scripts/spawnSync.ts @@ -0,0 +1,10 @@ +import { type SpawnSyncOptions, spawnSync as nodeSpawnSync } from 'node:child_process' + +export default function spawnSync(command: string, args?: readonly string[], options: SpawnSyncOptions = {}) { + if (!options.stdio) options.stdio = 'inherit' // I wanna know what's going on + if (!options.shell) options.shell = true // Windows requires this for PATHEXT support + const result = nodeSpawnSync(command, args, options) + if (result.error) throw result.error // Don't silently fail + if (result.status !== 0) process.exit(result.status) // Don't continue if a command fails + return result +} \ No newline at end of file diff --git a/scripts/test.ts b/scripts/test.ts new file mode 100644 index 0000000..4197700 --- /dev/null +++ b/scripts/test.ts @@ -0,0 +1,13 @@ +import fs from 'node:fs' +import spawnSync from './spawnSync.ts' +import download from './downloadProgress.ts' + +await download('https://mediafilez.forgecdn.net/files/7223/56/All%20the%20Mods%2010-5.1.zip', 'modpack.zip') + +fs.mkdirSync('test', { recursive: true }) +spawnSync('packwiz', ['curseforge', 'import', '../modpack.zip'], { cwd: 'test' }) +spawnSync('deno', ['run', '--allow-all', 'src/cli.ts', '--pack-file=test/pack.toml', 'cf','detect']) +spawnSync('deno', ['run', '--allow-all', 'src/cli.ts', '--pack-file=test/pack.toml', 'cf','urls']) +spawnSync('deno', ['run', '--allow-all', 'src/cli.ts', '--pack-file=test/pack.toml', 'mr','detect']) +spawnSync('deno', ['run', '--allow-all', 'src/cli.ts', '--pack-file=test/pack.toml', 'mr','merge']) +fs.rmSync('test', { recursive: true }) \ No newline at end of file diff --git a/src/cli.ts b/src/cli.ts index e69de29..b93313f 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -0,0 +1,95 @@ +import { Command, program } from "commander" +import { config } from "dotenv" +import * as packwiz from 'packwiz-extras-lib' +import * as fs from 'node:fs/promises' +import { stringifyTOML } from 'confbox' +import spawnSync from "./spawnSync.ts" + +async function refresh(packFile: packwiz.Path) { + const cwd = packFile.replace('pack.toml', '') + spawnSync('packwiz', ['refresh'], { cwd }) +} + +async function replace(results: Map) { + const jobs = [] + for (const [path, mod] of results.entries()) { + jobs.push(fs.rm(path)) + jobs.push(fs.writeFile(path + '.pw.toml', stringifyTOML(mod))) + } + await Promise.all(jobs) +} + +async function overwrite(results: Map) { + const jobs = [] + for (const [path, mod] of results.entries()) { + jobs.push(fs.writeFile(path, stringifyTOML(mod))) + } + await Promise.all(jobs) +} + +config({ 'quiet': true }) + +program.name('packwiz-extras') + .description('extra utilities for packwiz') + .option('--pack-file ', 'The modpack file to use (default "pack.toml")', 'pack.toml') + +const curseforge = program.command('curseforge').alias('cf') + .description('manage curseforge files') + +const cfKey = ['--api-key ', + 'Your curseforge api key. This is required by curseforge to access their API. ' + + 'Can also be provided via environment variable or .env file as CF_API_KEY', + process.env.CF_API_KEY] + +if (cfKey[2]) { + curseforge.option(cfKey[0], cfKey[1], cfKey[2]) +} else { + curseforge.requiredOption(cfKey[0], cfKey[1], cfKey[2]) +} + +curseforge.command('detect') + .description('detect and replace files availible on curseforge') + .action(async function () { + const apiKey = curseforge.opts().apiKey + const packFile = program.opts().packFile + const result = await packwiz.cfDetect(packFile, apiKey) + await replace(result) + await refresh(packFile) + }) + +curseforge.command('urls') + .description('cache curseforge download urls to speed up packwiz-installer') + .action(async function () { + const apiKey = curseforge.opts().apiKey + const packFile = program.opts().packFile + const result = await packwiz.cfUrl(packFile, apiKey) + await overwrite(result) + await refresh(packFile) + }) + +const modrith = program.command('modrinth').alias('mr') + .description('manage modrinth files') + +modrith.option('--api-key ', 'Your modrinth api key, optional.') + +modrith.command('detect') + .description('detect and replace files availible on modrinth') + .action(async function () { + const apiKey = modrith.opts().apiKey + const packFile = program.opts().packFile + const result = await packwiz.mrDetect(packFile, apiKey) + await replace(result) + await refresh(packFile) + }) + +modrith.command('merge') + .description('detect curseforge metafiles which are also availible on modrinth and merge their metadata') + .action(async function () { + const apiKey = modrith.opts().apiKey + const packFile = program.opts().packFile + const result = await packwiz.mrMerge(packFile, apiKey) + await overwrite(result) + await refresh(packFile) + }) + +await program.parseAsync() \ No newline at end of file diff --git a/src/spawnSync.ts b/src/spawnSync.ts new file mode 100644 index 0000000..789d5e5 --- /dev/null +++ b/src/spawnSync.ts @@ -0,0 +1,9 @@ +import { type SpawnSyncOptions, spawnSync as nodeSpawnSync } from 'node:child_process' + +export default function spawnSync(command: string, args?: readonly string[], options: SpawnSyncOptions = {}) { + if (!options.stdio) options.stdio = 'inherit' // I wanna know what's going on + const result = nodeSpawnSync(command, args, options) + if (result.error) throw result.error // Don't silently fail + if (result.status !== 0) process.exit(result.status) // Don't continue if a command fails + return result +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 2f0bf55..82c07c1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,6 +2,11 @@ "compilerOptions": { "target": "es2022", "module": "es2022", - "moduleResolution": "node" - } + "moduleResolution": "node", + "allowImportingTsExtensions": true, + "noEmit": true + }, + "include": [ + "src/" + ] } \ No newline at end of file