@pompeii-labs/cli
Version:
Magma CLI
136 lines (135 loc) • 4.08 kB
JavaScript
import fs from "fs";
import path from "path";
import { glob } from "glob";
import { UI } from "./ui.js";
import { saveAgent } from "./api.js";
import chalk from "chalk";
class Bundler {
constructor(projectDir, org) {
this.projectDir = projectDir;
this.org = org;
}
async run(verbose = true) {
if (verbose) {
const validateSpinner = UI.spinner("Validating project").start();
this.validateProject();
validateSpinner.succeed();
} else {
this.validateProject();
}
const existingAgentId = this.checkExistingAgent();
if (verbose) {
if (existingAgentId) {
console.log(chalk.dim(`
Updating existing agent: ${existingAgentId}`));
} else {
console.log(chalk.dim("\nCreating new agent"));
}
}
const files = this.collectFiles(verbose);
const packageFile = files.find((f) => f.path === "package.json");
const packageJson = JSON.parse(packageFile.content);
const deploySpinner = UI.spinner("Uploading package to Magma").start();
const agent = await saveAgent({
id: existingAgentId,
name: packageJson.name,
version: packageJson.version,
files,
org_id: this.org.id
});
deploySpinner.succeed();
this.updateAgentCache(agent);
return agent;
}
collectFiles(verbose = false) {
let fileSpinner;
if (verbose) {
fileSpinner = UI.spinner("Collecting agent source code").start();
}
const files = [];
const ignore = [
"package.json",
"tsconfig.json",
"bun.lock",
"node_modules/**",
"package-lock.json",
".env",
".git/**",
".github/**",
".magma/**",
"**/.DS_Store"
];
const packageJson = fs.readFileSync(path.join(this.projectDir, "package.json"), "utf-8");
if (!fs.existsSync(path.join(this.projectDir, "package.json"))) {
throw new Error(`package.json must exist at project root`);
}
files.push({ content: packageJson, path: "package.json" });
const tsConfig = JSON.parse(
fs.readFileSync(path.join(this.projectDir, "tsconfig.json"), "utf-8")
);
let outDir = tsConfig?.compilerOptions?.outDir;
if (outDir.startsWith("./")) {
outDir = outDir.replace("./", "");
}
if (outDir && outDir !== "") {
ignore.push(outDir + "/**");
}
files.push({ content: JSON.stringify(tsConfig, null, 4), path: "tsconfig.json" });
const matchFiles = glob.sync("**/*", {
cwd: this.projectDir,
nodir: true,
ignore,
dot: true
});
for (const file of matchFiles) {
const normalizedPath = path.normalize(file);
const content = fs.readFileSync(path.join(this.projectDir, normalizedPath), "utf8");
const linuxPath = file.replace(/\\/g, "/");
files.push({ content, path: linuxPath });
}
if (verbose) {
fileSpinner.succeed();
}
return files;
}
updateAgentCache(agent, verbose = false) {
let cacheSpinner;
if (verbose) {
cacheSpinner = UI.spinner("Caching local agent details").start();
}
const magmaCache = {
id: agent.id,
name: agent.name,
version: agent.version
};
if (!fs.existsSync(path.join(this.projectDir, ".magma"))) {
fs.mkdirSync(path.join(this.projectDir, ".magma"), { recursive: true });
if (fs.existsSync(path.join(this.projectDir, ".gitignore"))) {
fs.appendFileSync(path.join(this.projectDir, ".gitignore"), "\n.magma");
}
}
fs.writeFileSync(
path.join(this.projectDir, ".magma", ".cache"),
JSON.stringify(magmaCache, null, 4)
);
if (verbose) {
cacheSpinner.succeed();
}
}
validateProject() {
if (!fs.existsSync(this.projectDir)) {
throw new Error(`Project directory does not exist: ${this.projectDir}`);
}
}
checkExistingAgent() {
const cacheDir = path.join(this.projectDir, ".magma", ".cache");
if (fs.existsSync(cacheDir)) {
const cache = JSON.parse(fs.readFileSync(cacheDir, "utf8"));
return cache.id;
}
return void 0;
}
}
export {
Bundler
};