import { Command } from "jsr:@cliffy/command@1.0.0-rc.7";
import { HOST_URL, TOKEN } from "../config.ts";
export default new Command()
.name('run')
.alias('start')
.description('Runs an application hosted on Viapak')
.arguments('<name:string> [args...:string]')
.option('-v, --version <version:string>', 'Runs a specific version')
.example(
'Run latest version',
'run example'
)
.example(
'Run specific version',
'run example --version 1.0.0'
)
.action(async (_, name, ...args) => {
let version = 'latest';
const [ namespace ] = name.match(/@[^\/]+/) as string[];
name = name.replace(namespace + '/', '');
if(name.includes('@')) {
[name, version] = name.split('@');
}
let package_info: Record<string, any> = {};
try {
package_info = await (
await fetch(`${HOST_URL}/api/v1/packages/${namespace}/${name}`, {
headers: {
Authorization: `Bearer ${TOKEN}`
}
})
).json();
} catch(_) { /**/ }
if(!package_info.exists) {
console.log(`${name} could not be found.`)
console.log();
Deno.exit(0);
}
await runScript(`${HOST_URL}/${namespace}/${name}@${version}`, {
env: Deno.env.toObject(),
args,
});
});
const runScript = async (url: string, options?: Deno.CommandOptions) => {
try {
const command = new Deno.Command("deno", {
args: ["run", "-A", "-r", "-q", url, ...(options?.args ?? [])],
env: options?.env,
stdout: "piped",
stderr: "piped",
});
const process = command.spawn();
const stdoutReader = process.stdout.getReader();
const stderrReader = process.stderr.getReader();
const readStream = async (reader: ReadableStreamDefaultReader<Uint8Array>, type: "stdout" | "stderr") => {
while (true) {
const { done, value } = await reader.read();
if (done) break;
const text = new TextDecoder().decode(value);
if (type === "stdout") console.log(text);
else console.error(text);
}
};
await Promise.all([
readStream(stdoutReader, "stdout"),
readStream(stderrReader, "stderr"),
]);
const status = await process.status;
if (!status.success) {
throw new Error();
}
} catch (_) {
console.log();
console.error('Viapak > The script did not exit gracefully!');
console.log();
}
}