feat: migrate to npm specifiers with type-safe plugin index

- Default config and all 4 templates use @quartz-community/* npm specifiers
- config-loader: npm packages imported directly (not via .quartz/plugins/ paths)
- gitLoader: regeneratePluginIndex cross-references .d.ts with .js to correctly
  classify type-only exports, preventing runtime 'does not provide export' errors
- All 44 default plugins added as dependencies
- Locally tested: 111 docs files → 374 output files, zero errors
This commit is contained in:
saberzero1
2026-07-23 02:19:17 +02:00
parent 4b7ecb96f0
commit 11b9960663
9 changed files with 368 additions and 232 deletions
+46 -4
View File
@@ -951,8 +951,29 @@ export async function regeneratePluginIndex(
const dtsContent = fs.readFileSync(distIndex, "utf-8")
const exportedNames = parseExportsFromDts(dtsContent)
const named = exportedNames.filter((e) => !e.startsWith("type "))
const types = exportedNames.filter((e) => e.startsWith("type ")).map((e) => e.slice(5))
const dtsTypes = exportedNames.filter((e) => e.startsWith("type ")).map((e) => e.slice(5))
const dtsNamed = exportedNames.filter((e) => !e.startsWith("type "))
const jsIndex = path.join(pluginDir, "dist", "index.js")
let jsExports = new Set<string>()
if (fs.existsSync(jsIndex)) {
const jsContent = fs.readFileSync(jsIndex, "utf-8")
const jsExportMatches = jsContent.matchAll(/export\s*{\s*([^}]+)\s*}/g)
for (const m of jsExportMatches) {
for (const n of m[1].split(",")) {
const clean = n
.trim()
.split(/\s+as\s+/)
.pop()
?.trim()
if (clean) jsExports.add(clean)
}
}
}
const named = jsExports.size > 0 ? dtsNamed.filter((n) => jsExports.has(n)) : dtsNamed
const extraTypes = jsExports.size > 0 ? dtsNamed.filter((n) => !jsExports.has(n)) : []
const types = [...dtsTypes, ...extraTypes]
const overridable = named.filter((n) => isOverridableExport(n, dtsContent))
const passthrough = named.filter((n) => !isOverridableExport(n, dtsContent))
@@ -988,8 +1009,29 @@ export async function regeneratePluginIndex(
const dtsContent = fs.readFileSync(distIndex, "utf-8")
const exportedNames = parseExportsFromDts(dtsContent)
const named = exportedNames.filter((e) => !e.startsWith("type "))
const types = exportedNames.filter((e) => e.startsWith("type ")).map((e) => e.slice(5))
const dtsTypes = exportedNames.filter((e) => e.startsWith("type ")).map((e) => e.slice(5))
const dtsNamed = exportedNames.filter((e) => !e.startsWith("type "))
const jsIndex = path.join(path.dirname(distIndex), "index.js")
let jsExports = new Set<string>()
if (fs.existsSync(jsIndex)) {
const jsContent = fs.readFileSync(jsIndex, "utf-8")
const jsExportMatches = jsContent.matchAll(/export\s*{\s*([^}]+)\s*}/g)
for (const m of jsExportMatches) {
for (const n of m[1].split(",")) {
const clean = n
.trim()
.split(/\s+as\s+/)
.pop()
?.trim()
if (clean) jsExports.add(clean)
}
}
}
const named = jsExports.size > 0 ? dtsNamed.filter((n) => jsExports.has(n)) : dtsNamed
const extraTypes = jsExports.size > 0 ? dtsNamed.filter((n) => !jsExports.has(n)) : []
const types = [...dtsTypes, ...extraTypes]
const overridable = named.filter((n) => isOverridableExport(n, dtsContent))
const passthrough = named.filter((n) => !isOverridableExport(n, dtsContent))