#!/usr/bin/env bun /** * sync-deps.mjs - Merge submodule deps into consumer's package.json * * Usage: node atproto-presskit/scripts/sync-deps.mjs [--dry-run] * * Reads atproto-presskit/package.json, then for each dependency/devDependency * it adds (or version-bumps) the entry in the consumer's package.json. * Ensures patchedDependencies entry for sequoia-cli points at the * submodule's patch file. * * If --dry-run is passed, prints what would change without writing. */ import fs from "node:fs"; import path from "node:path"; import url from "node:url"; const __filename = url.fileURLToPath(new URL(import.meta.url)); const __dirname = path.dirname(__filename); // Resolved paths relative to repo root const rootDir = path.resolve(__dirname, ".."); const submodulePkgPath = path.join(rootDir, "package.json"); const consumerPkgPath = path.join(rootDir, "..", "package.json"); const patchesDir = path.join(rootDir, "patches"); console.log(`atproto-presskit root: ${rootDir}`); console.log(`submodule package: ${submodulePkgPath}`); console.log(`consumer package: ${consumerPkgPath}`); // Check for --dry-run flag const args = process.argv.slice(2); const dryRun = args.includes("--dry-run"); if (dryRun) { console.log("Dry-run mode: no changes will be written"); } // Read submodule package.json const submodulePkg = JSON.parse(fs.readFileSync(submodulePkgPath, "utf8")); console.log(`Found submodule package: ${submodulePkg.name}@${submodulePkg.version}`); // Dependencies to merge const depsToSync = { dependencies: submodulePkg.dependencies || {}, devDependencies: submodulePkg.devDependencies || {}, }; // Check for sequoia-cli patch const sequoiaPatchPath = path.join(patchesDir, "sequoia-cli@0.5.6.patch"); const hasPatch = fs.existsSync(sequoiaPatchPath); if (hasPatch) { console.log(`Found sequoia-cli patch: ${sequoiaPatchPath}`); } else { console.log("Warning: sequoia-cli patch not found at expected location"); } // Read consumer package.json let consumerPkg; try { consumerPkg = JSON.parse(fs.readFileSync(consumerPkgPath, "utf8")); } catch (err) { console.error(`Error reading consumer package: ${err.message}`); process.exit(1); } // Track changes const changes = { added: /** @type {string[]} */ ([]), updated: /** @type {string[]} */ ([]), }; // Merge dependencies and devDependencies /** @param {"dependencies"|"devDependencies"} section */ function mergeDeps(section) { const source = depsToSync[section]; const target = consumerPkg[section] || {}; for (const [name, version] of Object.entries(source)) { const current = target[name]; if (!current) { target[name] = version; changes.added.push(name + "@" + version); } else if (current !== version) { console.log(" Updating " + name + ": " + current + " -> " + version); target[name] = version; changes.updated.push(name + "@" + version); } else { console.log(" Keeping " + name + "@" + current); } } consumerPkg[section] = target; } console.log("\nMerging dependencies:"); mergeDeps("dependencies"); console.log("\nMerging devDependencies:"); mergeDeps("devDependencies"); // Update patchedDependencies if sequoia patch exists if (hasPatch) { if (!consumerPkg.patchedDependencies) { consumerPkg.patchedDependencies = {}; } // Path is relative to consumer (two dirs up from submodule) const patchRef = "atproto-presskit/patches/sequoia-cli@0.5.6.patch"; if (consumerPkg.patchedDependencies["sequoia-cli@0.5.6"] !== patchRef) { console.log(` Setting patchedDependencies["sequoia-cli@0.5.6"]: ${patchRef}`); consumerPkg.patchedDependencies["sequoia-cli@0.5.6"] = patchRef; } } // Write changes if not dry-run if (!dryRun) { fs.writeFileSync(consumerPkgPath, JSON.stringify(consumerPkg, null, 2) + "\n"); console.log(`\nWrote consumer package: ${consumerPkgPath}`); } else { console.log("\nDry-run complete. No changes written."); } // Print summary console.log("\n=== Summary ==="); console.log(`Added: ${changes.added.length} dependency/dep`); console.log(`Updated: ${changes.updated.length} dependency/dep`); if (dryRun) { console.log("\nWould commit these changes (not actually committed):"); console.log(" git add package.json"); console.log(' git commit -m "sync-deps: merge atproto-presskit dependencies"'); }