feat: support npm scoped package specifiers for plugins
Plugins can now be referenced as "@quartz-community/<name>" in quartz.config.yaml and via 'quartz plugin add'. The npm path skips git installation and resolves from node_modules. Changes: - gitLoader.ts: detect @scope/name as npm package in parsePluginSource() - config-loader.ts: skip git install for npm packages, read manifests from node_modules via createRequire - install-plugins.ts: filter npm packages from prebuild, fallback to YAML config parsing to avoid loading full quartz.ts - plugin-data.js: npm detection in CLI parseGitSource() - plugin-git-handlers.js: npm install path in handlePluginAdd() - package.json: add missing hast-util-from-html dependency
This commit is contained in:
@@ -1,19 +1,68 @@
|
||||
#!/usr/bin/env node
|
||||
import fs from "fs"
|
||||
import path from "path"
|
||||
import YAML from "yaml"
|
||||
import { installPlugins, parsePluginSource } from "./gitLoader.js"
|
||||
import config from "../../../quartz.js"
|
||||
import type { PluginSource, QuartzPluginsJson } from "./types.js"
|
||||
|
||||
function resolveConfigPath(): string {
|
||||
const configYamlPath = path.join(process.cwd(), "quartz.config.yaml")
|
||||
const defaultConfigYamlPath = path.join(process.cwd(), "quartz.config.default.yaml")
|
||||
const legacyPluginsJsonPath = path.join(process.cwd(), "quartz.plugins.json")
|
||||
const legacyDefaultPluginsJsonPath = path.join(process.cwd(), "quartz.plugins.default.json")
|
||||
|
||||
if (fs.existsSync(configYamlPath)) return configYamlPath
|
||||
if (fs.existsSync(legacyPluginsJsonPath)) return legacyPluginsJsonPath
|
||||
if (fs.existsSync(defaultConfigYamlPath)) return defaultConfigYamlPath
|
||||
if (fs.existsSync(legacyDefaultPluginsJsonPath)) return legacyDefaultPluginsJsonPath
|
||||
return configYamlPath
|
||||
}
|
||||
|
||||
function readPluginsJson(): QuartzPluginsJson | null {
|
||||
const configPath = resolveConfigPath()
|
||||
if (!fs.existsSync(configPath)) return null
|
||||
const raw = fs.readFileSync(configPath, "utf-8")
|
||||
if (configPath.endsWith(".yaml") || configPath.endsWith(".yml")) {
|
||||
return YAML.parse(raw)
|
||||
}
|
||||
return JSON.parse(raw)
|
||||
}
|
||||
|
||||
async function getExternalPluginSources(): Promise<PluginSource[]> {
|
||||
try {
|
||||
const module = await import("../../../quartz.js")
|
||||
const config = module.default ?? module
|
||||
const externalPlugins = config.externalPlugins
|
||||
if (Array.isArray(externalPlugins) && externalPlugins.length > 0) {
|
||||
return externalPlugins as PluginSource[]
|
||||
}
|
||||
} catch {
|
||||
// fall back to config yaml parsing
|
||||
}
|
||||
|
||||
const pluginsJson = readPluginsJson()
|
||||
const entries = pluginsJson?.plugins ?? []
|
||||
return entries.filter((entry) => entry.enabled !== false).map((entry) => entry.source)
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const quartzConfig: any = config
|
||||
const externalPlugins = quartzConfig.externalPlugins || []
|
||||
const externalPlugins = await getExternalPluginSources()
|
||||
|
||||
if (externalPlugins.length === 0) {
|
||||
console.log("No external plugins to install.")
|
||||
return
|
||||
}
|
||||
|
||||
console.log(`Installing ${externalPlugins.length} plugin(s) from Git...`)
|
||||
const specs = externalPlugins
|
||||
.map((source: PluginSource) => parsePluginSource(source))
|
||||
.filter((spec) => !spec.npmPackage)
|
||||
|
||||
const specs = externalPlugins.map((source: string) => parsePluginSource(source))
|
||||
if (specs.length === 0) {
|
||||
console.log("No external Git plugins to install.")
|
||||
return
|
||||
}
|
||||
|
||||
console.log(`Installing ${specs.length} plugin(s) from Git...`)
|
||||
const installed = await installPlugins(specs, { verbose: true })
|
||||
|
||||
if (installed.size === externalPlugins.length) {
|
||||
|
||||
Reference in New Issue
Block a user