mirror of
https://github.com/jackyzha0/quartz.git
synced 2026-03-21 21:45:42 -05:00
feat: add PageTypePluginEntry for cross-boundary type compatibility
Introduce PageTypePluginEntry with never[] parameter types to accept both internal and community PageType plugins in config arrays without casts, working around branded FullSlug contravariance mismatch.
This commit is contained in:
parent
68f3c3fadd
commit
fd36066fdf
@ -2,7 +2,7 @@ import {
|
||||
QuartzTransformerPluginInstance,
|
||||
QuartzFilterPluginInstance,
|
||||
QuartzEmitterPluginInstance,
|
||||
QuartzPageTypePluginInstance,
|
||||
PageTypePluginEntry,
|
||||
} from "./types"
|
||||
import { LoadedPlugin } from "./loader/types"
|
||||
|
||||
@ -10,7 +10,7 @@ export interface PluginConfiguration {
|
||||
transformers: (QuartzTransformerPluginInstance | LoadedPlugin)[]
|
||||
filters: (QuartzFilterPluginInstance | LoadedPlugin)[]
|
||||
emitters: (QuartzEmitterPluginInstance | LoadedPlugin)[]
|
||||
pageTypes?: (QuartzPageTypePluginInstance | LoadedPlugin)[]
|
||||
pageTypes?: (PageTypePluginEntry | LoadedPlugin)[]
|
||||
}
|
||||
|
||||
export function isLoadedPlugin(plugin: unknown): plugin is LoadedPlugin {
|
||||
@ -29,14 +29,14 @@ export function getPluginInstance<T extends object | undefined>(
|
||||
| QuartzTransformerPluginInstance
|
||||
| QuartzFilterPluginInstance
|
||||
| QuartzEmitterPluginInstance
|
||||
| QuartzPageTypePluginInstance
|
||||
| PageTypePluginEntry
|
||||
| LoadedPlugin,
|
||||
options?: T,
|
||||
):
|
||||
| QuartzTransformerPluginInstance
|
||||
| QuartzFilterPluginInstance
|
||||
| QuartzEmitterPluginInstance
|
||||
| QuartzPageTypePluginInstance {
|
||||
| PageTypePluginEntry {
|
||||
if (isLoadedPlugin(plugin)) {
|
||||
const factory = plugin.plugin as (
|
||||
opts?: T,
|
||||
@ -44,7 +44,7 @@ export function getPluginInstance<T extends object | undefined>(
|
||||
| QuartzTransformerPluginInstance
|
||||
| QuartzFilterPluginInstance
|
||||
| QuartzEmitterPluginInstance
|
||||
| QuartzPageTypePluginInstance
|
||||
| PageTypePluginEntry
|
||||
return factory(options)
|
||||
}
|
||||
return plugin
|
||||
|
||||
@ -2,7 +2,7 @@ import { PluggableList } from "unified"
|
||||
import { StaticResources } from "../util/resources"
|
||||
import { ProcessedContent, QuartzPluginData } from "./vfile"
|
||||
import { QuartzComponent, QuartzComponentConstructor } from "../components/types"
|
||||
import { FilePath, FullSlug } from "../util/path"
|
||||
import { FilePath } from "../util/path"
|
||||
import { BuildCtx } from "../util/ctx"
|
||||
import { GlobalConfiguration } from "../cfg"
|
||||
import { VFile } from "vfile"
|
||||
@ -11,7 +11,7 @@ export interface PluginTypes {
|
||||
transformers: QuartzTransformerPluginInstance[]
|
||||
filters: QuartzFilterPluginInstance[]
|
||||
emitters: QuartzEmitterPluginInstance[]
|
||||
pageTypes?: QuartzPageTypePluginInstance[]
|
||||
pageTypes?: PageTypePluginEntry[]
|
||||
}
|
||||
|
||||
type OptionType = object | undefined
|
||||
@ -70,62 +70,50 @@ export type QuartzEmitterPluginInstance = {
|
||||
// PageType Plugin Types
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* Matcher function: determines if a source file belongs to a page type.
|
||||
* Returns true if the page type should own this file.
|
||||
*/
|
||||
export type PageMatcher = (args: {
|
||||
slug: FullSlug
|
||||
slug: string
|
||||
fileData: QuartzPluginData
|
||||
cfg: GlobalConfiguration
|
||||
[key: string]: unknown
|
||||
}) => boolean
|
||||
|
||||
/**
|
||||
* Virtual page descriptor for page types that generate pages
|
||||
* from aggregated data (e.g., tag indexes, folder listings).
|
||||
*/
|
||||
export interface VirtualPage {
|
||||
slug: FullSlug
|
||||
slug: string
|
||||
title: string
|
||||
data: Partial<QuartzPluginData>
|
||||
data: Partial<QuartzPluginData> & Record<string, unknown>
|
||||
}
|
||||
|
||||
/**
|
||||
* Generator function: produces virtual pages from all processed content.
|
||||
* Used by page types that don't match source files but instead create
|
||||
* synthetic pages (e.g., one page per tag, one page per folder).
|
||||
*/
|
||||
export type PageGenerator = (args: {
|
||||
content: ProcessedContent[]
|
||||
cfg: GlobalConfiguration
|
||||
ctx: BuildCtx
|
||||
[key: string]: unknown
|
||||
}) => VirtualPage[]
|
||||
|
||||
/**
|
||||
* Factory function that creates a PageType plugin instance.
|
||||
*/
|
||||
export type QuartzPageTypePlugin<Options extends OptionType = undefined> = (
|
||||
opts?: Options,
|
||||
) => QuartzPageTypePluginInstance
|
||||
|
||||
/**
|
||||
* A PageType plugin instance.
|
||||
*
|
||||
* PageTypes are a declarative abstraction over page-rendering emitters.
|
||||
* Each PageType declares which files it owns (via `match`), optionally
|
||||
* generates virtual pages (via `generate`), and provides a body component
|
||||
* and layout reference for rendering.
|
||||
*/
|
||||
export type QuartzPageTypePluginInstance = {
|
||||
export interface QuartzPageTypePluginInstance {
|
||||
name: string
|
||||
/** Higher priority wins when multiple page types match the same file. Default: 0. */
|
||||
priority?: number
|
||||
/** Determines which source files this page type owns. */
|
||||
match: PageMatcher
|
||||
/** Produces virtual pages from aggregated content data. */
|
||||
generate?: PageGenerator
|
||||
/** Layout key — references a key in `layout.byPageType`. */
|
||||
layout: string
|
||||
/** The body component constructor for this page type. */
|
||||
body: QuartzComponentConstructor
|
||||
}
|
||||
|
||||
// Structural supertype accepted in plugin configuration arrays.
|
||||
// Community plugins use a differently-branded FullSlug in their PageMatcher,
|
||||
// making them incompatible with the internal PageMatcher under strict
|
||||
// function-parameter contravariance. This wider entry type avoids forcing
|
||||
// casts in quartz.config.ts while the dispatcher safely calls match/generate
|
||||
// with the correct arguments at runtime.
|
||||
export interface PageTypePluginEntry {
|
||||
name: string
|
||||
priority?: number
|
||||
match: (...args: never[]) => boolean
|
||||
generate?: (...args: never[]) => VirtualPage[]
|
||||
layout: string
|
||||
body: QuartzComponentConstructor
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user