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:
saberzero1
2026-07-23 01:17:53 +02:00
parent 9cf87ff1c2
commit 5b34917e98
7 changed files with 369 additions and 8 deletions
+12 -2
View File
@@ -2,6 +2,7 @@ import fs from "fs"
import path from "path"
import YAML from "yaml"
import { styleText } from "util"
import { createRequire } from "node:module"
import { QuartzConfig, GlobalConfiguration, FullPageLayout } from "../../cfg"
import { QuartzComponent, QuartzComponentConstructor } from "../../components/types"
import { PluginTypes } from "../types"
@@ -200,8 +201,14 @@ async function resolvePluginManifest(source: PluginSource): Promise<PluginManife
async function readManifestFromPackageJson(source: PluginSource): Promise<PluginManifest | null> {
try {
const gitSpec = parsePluginSource(source)
const pluginDir = path.join(process.cwd(), ".quartz", "plugins", gitSpec.name)
const pkgPath = path.join(pluginDir, "package.json")
const require = createRequire(import.meta.url)
let pkgPath: string
if (gitSpec.npmPackage) {
pkgPath = require.resolve(`${gitSpec.name}/package.json`, { paths: [process.cwd()] })
} else {
const pluginDir = path.join(process.cwd(), ".quartz", "plugins", gitSpec.name)
pkgPath = path.join(pluginDir, "package.json")
}
if (!fs.existsSync(pkgPath)) return null
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"))
@@ -259,6 +266,9 @@ export async function loadQuartzConfig(
for (const entry of enabledEntries) {
try {
const gitSpec = parsePluginSource(entry.source)
if (gitSpec.npmPackage) {
continue
}
const result = await installPlugin(gitSpec, { verbose: false })
if (result.nativeDeps.size > 0) {
allNativeDeps.set(gitSpec.name, result.nativeDeps)