publish-sequential.js
1 #!/usr/bin/env node 2 3 /** 4 * Sequential publish script that builds all packages first, 5 * then publishes them in dependency order so dependencies are available 6 */ 7 8 const { execSync } = require("node:child_process"); 9 const fs = require("node:fs"); 10 const path = require("node:path"); 11 12 // Define dependency order (leaf packages first) 13 const publishOrder = [ 14 "debug", // No dependencies 15 "store", // No dependencies 16 "memory", // Depends on debug 17 "artifacts", // Depends on store 18 "devtools", // Depends on store 19 "cache", // Depends on artifacts 20 "agents", // Depends on debug, memory 21 "ai-sdk-tools", // Depends on everything 22 ]; 23 24 function getPackagePath(packageName) { 25 return path.join(__dirname, "..", "packages", packageName); 26 } 27 28 function getPackageJsonPath(packageName) { 29 return path.join(getPackagePath(packageName), "package.json"); 30 } 31 32 function readPackageJson(packageName) { 33 const filePath = getPackageJsonPath(packageName); 34 return JSON.parse(fs.readFileSync(filePath, "utf8")); 35 } 36 37 function writePackageJson(packageName, packageJson) { 38 const filePath = getPackageJsonPath(packageName); 39 fs.writeFileSync(filePath, `${JSON.stringify(packageJson, null, 2)}\n`); 40 } 41 42 // Store original prepublishOnly scripts 43 const originalPrepublishOnly = {}; 44 45 function disablePrepublishOnly(packageName) { 46 const packageJson = readPackageJson(packageName); 47 if (packageJson.scripts?.prepublishOnly) { 48 originalPrepublishOnly[packageName] = packageJson.scripts.prepublishOnly; 49 // Replace with just build (no clean) since dist already exists 50 packageJson.scripts.prepublishOnly = "bun run build"; 51 writePackageJson(packageName, packageJson); 52 } 53 } 54 55 function restorePrepublishOnly(packageName) { 56 const packageJson = readPackageJson(packageName); 57 if (originalPrepublishOnly[packageName] !== undefined) { 58 packageJson.scripts.prepublishOnly = originalPrepublishOnly[packageName]; 59 writePackageJson(packageName, packageJson); 60 } 61 } 62 63 function buildPackage(packageName) { 64 console.log(`\nšØ Building ${packageName}...`); 65 const packagePath = getPackagePath(packageName); 66 const packageJson = readPackageJson(packageName); 67 68 // Check if clean script exists, otherwise just build 69 const hasCleanScript = packageJson.scripts?.clean; 70 if (hasCleanScript) { 71 execSync("bun run clean && bun run build", { 72 cwd: packagePath, 73 stdio: "inherit", 74 }); 75 } else { 76 execSync("bun run build", { 77 cwd: packagePath, 78 stdio: "inherit", 79 }); 80 } 81 } 82 83 function publishPackage(packageName) { 84 console.log(`\nš¦ Publishing ${packageName}...`); 85 const packagePath = getPackagePath(packageName); 86 // Temporarily disable clean in prepublishOnly 87 disablePrepublishOnly(packageName); 88 89 try { 90 execSync("npm publish", { 91 cwd: packagePath, 92 stdio: "inherit", 93 }); 94 console.log(`ā Published ${packageName}`); 95 } finally { 96 // Restore original prepublishOnly 97 restorePrepublishOnly(packageName); 98 } 99 } 100 101 async function main() { 102 console.log("š Building all packages first...\n"); 103 104 // Build all packages in dependency order 105 for (const packageName of publishOrder) { 106 buildPackage(packageName); 107 } 108 109 console.log("\nā All packages built successfully!\n"); 110 console.log("š¦ Publishing packages sequentially...\n"); 111 112 // Publish packages sequentially 113 for (const packageName of publishOrder) { 114 publishPackage(packageName); 115 } 116 117 console.log("\nš All packages published successfully!"); 118 } 119 120 main().catch((error) => { 121 console.error("ā Error:", error); 122 process.exit(1); 123 });