diff --git a/quartz/cli/plugin-data.js b/quartz/cli/plugin-data.js index b8e1958..c8cd6b4 100644 --- a/quartz/cli/plugin-data.js +++ b/quartz/cli/plugin-data.js @@ -58,7 +58,7 @@ export function writePluginsJson(data) { writeDataToFile(CONFIG_YAML_PATH, rest) } -export function readDefaultPluginsJson() { +function readDefaultPluginsJson() { const defaultPath = resolveDefaultConfigPath() return readFileAsData(defaultPath) } @@ -99,7 +99,7 @@ export function getSourceUrl(source) { /** * Returns the subdir from an object source, or undefined for string sources. */ -export function getSourceSubdir(source) { +function getSourceSubdir(source) { if (typeof source === "object" && source !== null && typeof source.subdir === "string") { return source.subdir } @@ -201,80 +201,6 @@ export function getGitCommit(pluginDir) { } } -export function getPluginDir(name) { - return path.join(PLUGINS_DIR, name) -} - -export function pluginDirExists(name) { - return fs.existsSync(path.join(PLUGINS_DIR, name)) -} - -export function ensurePluginsDir() { - if (!fs.existsSync(PLUGINS_DIR)) { - fs.mkdirSync(PLUGINS_DIR, { recursive: true }) - } -} - -/** - * Merges quartz.config.yaml, quartz.lock.json, and on-disk manifest data - * into enriched plugin entries with: name, displayName, source, enabled, - * options, order, layout, category, installed, locked, manifest, - * currentCommit, modified. - */ -export function getEnrichedPlugins() { - const pluginsJson = readPluginsJson() - const lockfile = readLockfile() - - if (!pluginsJson?.plugins) return [] - - return pluginsJson.plugins.map((entry, index) => { - const name = extractPluginName(entry.source) - const pluginDir = path.join(PLUGINS_DIR, name) - const installed = fs.existsSync(pluginDir) - const locked = lockfile?.plugins?.[name] ?? null - const manifest = installed ? readManifestFromPackageJson(pluginDir) : null - const currentCommit = installed ? getGitCommit(pluginDir) : null - const modified = locked && currentCommit ? currentCommit !== locked.commit : false - - return { - index, - name, - displayName: manifest?.displayName ?? name, - source: entry.source, - sourceDisplay: formatSource(entry.source), - subdir: getSourceSubdir(entry.source) ?? locked?.subdir ?? undefined, - enabled: entry.enabled ?? true, - options: entry.options ?? {}, - order: entry.order ?? 50, - layout: entry.layout ?? null, - category: manifest?.category ?? "unknown", - installed, - locked, - manifest, - currentCommit, - modified, - } - }) -} - -export function getLayoutConfig() { - const pluginsJson = readPluginsJson() - return pluginsJson?.layout ?? null -} - -export function getGlobalConfig() { - const pluginsJson = readPluginsJson() - return pluginsJson?.configuration ?? null -} - -export function updatePluginEntry(index, updates) { - const json = readPluginsJson() - if (!json?.plugins?.[index]) return false - Object.assign(json.plugins[index], updates) - writePluginsJson(json) - return true -} - export function updateGlobalConfig(updates) { const json = readPluginsJson() if (!json) return false @@ -283,40 +209,6 @@ export function updateGlobalConfig(updates) { return true } -export function updateLayoutConfig(layout) { - const json = readPluginsJson() - if (!json) return false - json.layout = layout - writePluginsJson(json) - return true -} - -export function reorderPlugin(fromIndex, toIndex) { - const json = readPluginsJson() - if (!json?.plugins) return false - const [moved] = json.plugins.splice(fromIndex, 1) - json.plugins.splice(toIndex, 0, moved) - writePluginsJson(json) - return true -} - -export function removePluginEntry(index) { - const json = readPluginsJson() - if (!json?.plugins?.[index]) return false - json.plugins.splice(index, 1) - writePluginsJson(json) - return true -} - -export function addPluginEntry(entry) { - const json = readPluginsJson() - if (!json) return false - if (!json.plugins) json.plugins = [] - json.plugins.push(entry) - writePluginsJson(json) - return true -} - export function configExists() { return fs.existsSync(CONFIG_YAML_PATH) || fs.existsSync(LEGACY_PLUGINS_JSON_PATH) } diff --git a/quartz/cli/plugin-git-handlers.js b/quartz/cli/plugin-git-handlers.js index a62d0cd..70d9875 100644 --- a/quartz/cli/plugin-git-handlers.js +++ b/quartz/cli/plugin-git-handlers.js @@ -1,7 +1,7 @@ import fs from "fs" import path from "path" import os from "os" -import { execSync, exec as execCb } from "child_process" +import { exec as execCb } from "child_process" import { styleText, promisify } from "util" import { readPluginsJson, @@ -25,25 +25,6 @@ const INTERNAL_EXPORTS = new Set(["manifest", "default"]) const execAsync = promisify(execCb) -function cloneWithSubdir({ url, ref, subdir, pluginDir }) { - const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "quartz-plugin-")) - try { - if (ref) { - execSync(`git clone --depth 1 --branch ${ref} "${url}" "${tmpDir}"`, { stdio: "ignore" }) - } else { - execSync(`git clone --depth 1 "${url}" "${tmpDir}"`, { stdio: "ignore" }) - } - const subdirPath = path.join(tmpDir, subdir) - if (!fs.existsSync(subdirPath)) { - throw new Error(`Subdirectory "${subdir}" not found in cloned repository`) - } - fs.cpSync(subdirPath, pluginDir, { recursive: true }) - return getGitCommit(tmpDir) - } finally { - fs.rmSync(tmpDir, { recursive: true, force: true }) - } -} - async function cloneWithSubdirAsync({ url, ref, subdir, pluginDir }) { const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "quartz-plugin-")) try { @@ -64,30 +45,6 @@ async function cloneWithSubdirAsync({ url, ref, subdir, pluginDir }) { } } -function buildPlugin(pluginDir, name) { - try { - const skipBuild = !needsBuild(pluginDir) - console.log(styleText("cyan", ` → ${name}: installing dependencies...`)) - execSync("npm install --ignore-scripts", { cwd: pluginDir, stdio: "ignore" }) - if (!skipBuild) { - console.log(styleText("cyan", ` → ${name}: building...`)) - execSync("npm run build", { cwd: pluginDir, stdio: "ignore" }) - } - // Remove devDependencies after build — they are no longer needed and their - // presence can cause duplicate-singleton issues when a plugin ships its own - // copy of a shared dependency (e.g. bases-page's ViewRegistry). - execSync("npm prune --omit=dev", { cwd: pluginDir, stdio: "ignore" }) - // Symlink peerDependencies: @quartz-community/* peers resolve to sibling - // plugins, all other peers resolve to the host Quartz node_modules so that - // plugins share a single copy of packages like unified, vfile, etc. - linkPeerPlugins(pluginDir) - return true - } catch (error) { - console.log(styleText("red", ` ✗ ${name}: build failed`)) - return false - } -} - async function buildPluginAsync(pluginDir, name) { try { const skipBuild = !needsBuild(pluginDir) diff --git a/quartz/cli/plugin-handlers.js b/quartz/cli/plugin-handlers.js deleted file mode 100644 index ce5b18e..0000000 --- a/quartz/cli/plugin-handlers.js +++ /dev/null @@ -1,130 +0,0 @@ -import { styleText } from "util" -import { execSync, spawnSync } from "child_process" -import fs from "fs" -import path from "path" - -export async function handlePluginInstall(packageNames) { - console.log(`\n${styleText(["bgGreen", "black"], " Quartz Plugin Manager ")}\n`) - - if (packageNames.length === 0) { - console.log(styleText("red", "Error: No package names provided")) - console.log("Usage: npx quartz plugin install [package-name...]") - process.exit(1) - } - - console.log(`Installing ${packageNames.length} plugin(s)...`) - - const npmArgs = ["install", ...packageNames] - const result = spawnSync("npm", npmArgs, { stdio: "inherit" }) - - if (result.status !== 0) { - console.log(styleText("red", "Failed to install plugins")) - process.exit(1) - } - - console.log(styleText("green", "✓ Plugins installed successfully")) - console.log("\nAdd them to your quartz.config.yaml:") - - for (const pkg of packageNames) { - console.log(` import { Plugin } from "${pkg}"`) - } -} - -export async function handlePluginList() { - console.log(`\n${styleText(["bgGreen", "black"], " Quartz Plugin Manager ")}\n`) - - const packageJsonPath = path.join(process.cwd(), "package.json") - - if (!fs.existsSync(packageJsonPath)) { - console.log(styleText("red", "No package.json found")) - process.exit(1) - } - - const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8")) - const allDeps = { - ...packageJson.dependencies, - ...packageJson.devDependencies, - } - - const quartzPlugins = Object.entries(allDeps).filter(([name]) => { - return ( - name.startsWith("@quartz/") || - name.startsWith("quartz-") || - name.startsWith("@quartz-community/") - ) - }) - - if (quartzPlugins.length === 0) { - console.log("No Quartz plugins found in this project.") - console.log("Install plugins with: npx quartz plugin install ") - return - } - - console.log(`Found ${quartzPlugins.length} Quartz plugin(s):\n`) - - for (const [name, version] of quartzPlugins) { - console.log(` ${styleText("cyan", name)}@${version}`) - } -} - -export async function handlePluginSearch(query) { - console.log(`\n${styleText(["bgGreen", "black"], " Quartz Plugin Manager ")}\n`) - - const searchQuery = query || "quartz-plugin" - - console.log(`Searching npm for packages matching "${searchQuery}"...`) - console.log(styleText("gray", "(This may take a moment)\n")) - - try { - const result = execSync(`npm search ${searchQuery} --json`, { encoding: "utf-8" }) - const packages = JSON.parse(result) - - const quartzPlugins = packages.filter( - (pkg) => - pkg.name.startsWith("@quartz/") || - pkg.name.startsWith("quartz-") || - pkg.name.startsWith("@quartz-community/"), - ) - - if (quartzPlugins.length === 0) { - console.log("No Quartz plugins found matching your query.") - return - } - - console.log(`Found ${quartzPlugins.length} Quartz plugin(s):\n`) - - for (const pkg of quartzPlugins.slice(0, 20)) { - console.log(` ${styleText("cyan", pkg.name)}@${pkg.version}`) - if (pkg.description) { - console.log(` ${styleText("gray", pkg.description)}`) - } - console.log() - } - } catch { - console.log(styleText("yellow", "Could not search npm. Try visiting:")) - console.log(" https://www.npmjs.com/search?q=quartz-plugin") - } -} - -export async function handlePluginUninstall(packageNames) { - console.log(`\n${styleText(["bgGreen", "black"], " Quartz Plugin Manager ")}\n`) - - if (packageNames.length === 0) { - console.log(styleText("red", "Error: No package names provided")) - console.log("Usage: npx quartz plugin uninstall [package-name...]") - process.exit(1) - } - - console.log(`Uninstalling ${packageNames.length} plugin(s)...`) - - const npmArgs = ["uninstall", ...packageNames] - const result = spawnSync("npm", npmArgs, { stdio: "inherit" }) - - if (result.status !== 0) { - console.log(styleText("red", "Failed to uninstall plugins")) - process.exit(1) - } - - console.log(styleText("green", "✓ Plugins uninstalled successfully")) - console.log(styleText("yellow", "Don't forget to remove them from your quartz.config.yaml!")) -}