Refactor plugin/config loading, add theme-only plugin package support (#20556)
This commit is contained in:
@@ -50,6 +50,10 @@ function resolveExportPath(raw: string, dir: string) {
|
||||
return path.resolve(dir, raw)
|
||||
}
|
||||
|
||||
function isAbsolutePath(raw: string) {
|
||||
return path.isAbsolute(raw) || /^[A-Za-z]:[\\/]/.test(raw)
|
||||
}
|
||||
|
||||
function extractExportValue(value: unknown): string | undefined {
|
||||
if (typeof value === "string") return value
|
||||
if (!isRecord(value)) return undefined
|
||||
@@ -68,14 +72,18 @@ function packageMain(pkg: PluginPackage) {
|
||||
return next
|
||||
}
|
||||
|
||||
function resolvePackagePath(spec: string, raw: string, kind: PluginKind, pkg: PluginPackage) {
|
||||
function resolvePackageFile(spec: string, raw: string, kind: string, pkg: PluginPackage) {
|
||||
const resolved = resolveExportPath(raw, pkg.dir)
|
||||
const root = Filesystem.resolve(pkg.dir)
|
||||
const next = Filesystem.resolve(resolved)
|
||||
if (!Filesystem.contains(root, next)) {
|
||||
throw new Error(`Plugin ${spec} resolved ${kind} entry outside plugin directory`)
|
||||
}
|
||||
return pathToFileURL(next).href
|
||||
return next
|
||||
}
|
||||
|
||||
function resolvePackagePath(spec: string, raw: string, kind: PluginKind, pkg: PluginPackage) {
|
||||
return pathToFileURL(resolvePackageFile(spec, raw, kind, pkg)).href
|
||||
}
|
||||
|
||||
function resolvePackageEntrypoint(spec: string, kind: PluginKind, pkg: PluginPackage) {
|
||||
@@ -106,7 +114,7 @@ async function resolveDirectoryIndex(dir: string) {
|
||||
async function resolveTargetDirectory(target: string) {
|
||||
const file = targetPath(target)
|
||||
if (!file) return
|
||||
const stat = Filesystem.stat(file)
|
||||
const stat = await Filesystem.statAsync(file)
|
||||
if (!stat?.isDirectory()) return
|
||||
return file
|
||||
}
|
||||
@@ -147,13 +155,13 @@ async function resolvePluginEntrypoint(spec: string, target: string, kind: Plugi
|
||||
}
|
||||
|
||||
export function isPathPluginSpec(spec: string) {
|
||||
return spec.startsWith("file://") || spec.startsWith(".") || path.isAbsolute(spec) || /^[A-Za-z]:[\\/]/.test(spec)
|
||||
return spec.startsWith("file://") || spec.startsWith(".") || isAbsolutePath(spec)
|
||||
}
|
||||
|
||||
export async function resolvePathPluginTarget(spec: string) {
|
||||
const raw = spec.startsWith("file://") ? fileURLToPath(spec) : spec
|
||||
const file = path.isAbsolute(raw) || /^[A-Za-z]:[\\/]/.test(raw) ? raw : path.resolve(raw)
|
||||
const stat = Filesystem.stat(file)
|
||||
const stat = await Filesystem.statAsync(file)
|
||||
if (!stat?.isDirectory()) {
|
||||
if (spec.startsWith("file://")) return spec
|
||||
return pathToFileURL(file).href
|
||||
@@ -190,7 +198,7 @@ export async function resolvePluginTarget(spec: string, parsed = parsePluginSpec
|
||||
|
||||
export async function readPluginPackage(target: string): Promise<PluginPackage> {
|
||||
const file = target.startsWith("file://") ? fileURLToPath(target) : target
|
||||
const stat = Filesystem.stat(file)
|
||||
const stat = await Filesystem.statAsync(file)
|
||||
const dir = stat?.isDirectory() ? file : path.dirname(file)
|
||||
const pkg = path.join(dir, "package.json")
|
||||
const json = await Filesystem.readJson<Record<string, unknown>>(pkg)
|
||||
@@ -211,6 +219,32 @@ export async function createPluginEntry(spec: string, target: string, kind: Plug
|
||||
}
|
||||
}
|
||||
|
||||
export function readPackageThemes(spec: string, pkg: PluginPackage) {
|
||||
const field = pkg.json["oc-themes"]
|
||||
if (field === undefined) return []
|
||||
if (!Array.isArray(field)) {
|
||||
throw new TypeError(`Plugin ${spec} has invalid oc-themes field`)
|
||||
}
|
||||
|
||||
const list = field.map((item) => {
|
||||
if (typeof item !== "string") {
|
||||
throw new TypeError(`Plugin ${spec} has invalid oc-themes entry`)
|
||||
}
|
||||
|
||||
const raw = item.trim()
|
||||
if (!raw) {
|
||||
throw new TypeError(`Plugin ${spec} has empty oc-themes entry`)
|
||||
}
|
||||
if (raw.startsWith("file://") || isAbsolutePath(raw)) {
|
||||
throw new TypeError(`Plugin ${spec} oc-themes entry must be relative: ${item}`)
|
||||
}
|
||||
|
||||
return resolvePackageFile(spec, raw, "oc-themes", pkg)
|
||||
})
|
||||
|
||||
return Array.from(new Set(list))
|
||||
}
|
||||
|
||||
export function readPluginId(id: unknown, spec: string) {
|
||||
if (id === undefined) return
|
||||
if (typeof id !== "string") throw new TypeError(`Plugin ${spec} has invalid id type ${typeof id}`)
|
||||
|
||||
Reference in New Issue
Block a user