import { existsSync } from "jsr:@std/fs/exists";
import { Command } from "jsr:@cliffy/command@1.0.0-rc.7";
import { HOST_URL, TOKEN } from "../config.ts";
import { join } from "jsr:@std/path@1.0.8/join";
import { ScanPublishableFiles } from "../../utils/scan_files.ts";
import { FileSize } from "../../utils/file_size.ts";
import { Zip } from "../../modules/zip.ts";
interface DenoMeta {
name?: string
version?: string
tasks?: { 'viapak:build': string | undefined }
tags?: string[]
}
export default new Command()
.name('publish')
.alias('push')
.description('Publishes the current code to Viapak under a new version')
.option('--force', 'If the current version already exists, overwrite it.')
.action(async (options) => {
try {
const __dirname = Deno.cwd();
const deno_json_path = join(__dirname, 'deno.json');
if(!existsSync(deno_json_path, { isFile: true })) throw new Error('deno.json not found. Are you running this in a project root directory?');
let { name, version, tasks, tags } = JSON.parse(Deno.readTextFileSync(join(__dirname, 'deno.json')) ?? "{}") as DenoMeta;
tags ||= [];
if(!name) throw new Error('Please add a package name to your deno.json');
if(!version) throw new Error('Please add a package version to your deno.json');
console.log(`Publishing %c${name}@${version}%c...`, "color: #ffaa00", "color: inherit");
if(tags.length > 0) console.log(` '- tags: %c${tags.map(t => `#${t}`).join(' ')}`, "color: #00AAFF");
if(tasks?.["viapak:build"]) {
console.log(` '- Found a viapak build step. Executing...`)
const run_viapak_build = new Deno.Command('deno', {
args: ['task', 'viapak:build']
});
const { stdout, stderr } = await run_viapak_build.output();
if(stderr.length) {
console.error(` '-`, new TextDecoder().decode(stderr));
} else {
console.log(` '-`, new TextDecoder().decode(stdout));
}
}
console.log(` '- Compressing package...`);
const files = ScanPublishableFiles(__dirname);
const temp_publish_zip_path = join(__dirname, '_publish.zip');
if(existsSync(temp_publish_zip_path)) Deno.removeSync(temp_publish_zip_path);
await Zip.Process(files, { destination_file_path: temp_publish_zip_path }).then(async zip => {
console.log(` '- Uploading package... (${FileSize(zip.length)})`);
const headers = new Headers({
'Content-Type': 'application/zip',
'Content-Length': zip.length.toString(),
'Authorization': `Bearer ${TOKEN}`,
'X-Tags': JSON.stringify(tags)
})
const FORCE = options.force;
if(FORCE) {
console.log(" X You have set the %c--force%c flag to overwrite ${name}@${version} if it exists. Are you sure? This can't be undone!", "color: red", "color: inherit")
const confirm_force = confirm("Force?");
if(!confirm_force) {
console.log();
Deno.exit(0);
}
headers.append('X-Force', 'TRUE');
}
const req = new Request(new URL(`publish/${name}@${version}`, HOST_URL), {
method: 'PUT',
headers,
body: zip.stream,
});
const response = await fetch(req);
if(!response.ok) {
throw new Error(await response.text());
}
console.log(` '- ${name}@${version} ${FORCE ? 'overwritten' : 'published'}!`);
Deno.exit(0);
});
} catch(e: any) {
console.error(` '- Could not publish!`);
console.error(` ${e.message}`);
Deno.exit(0);
}
console.log("");
});