Переглянути джерело

refactor: unwrap ConfigPlugin namespace to flat exports + self-reexport (#22876)

Kit Langton 2 днів тому
батько
коміт
32548bcb4a
1 змінених файлів з 67 додано та 67 видалено
  1. 67 67
      packages/opencode/src/config/plugin.ts

+ 67 - 67
packages/opencode/src/config/plugin.ts

@@ -4,81 +4,81 @@ import { pathToFileURL } from "url"
 import { isPathPluginSpec, parsePluginSpecifier, resolvePathPluginTarget } from "@/plugin/shared"
 import path from "path"
 
-export namespace ConfigPlugin {
-  const Options = z.record(z.string(), z.unknown())
-  export type Options = z.infer<typeof Options>
-
-  // Spec is the user-config value: either just a plugin identifier, or the identifier plus inline options.
-  // It answers "what should we load?" but says nothing about where that value came from.
-  export const Spec = z.union([z.string(), z.tuple([z.string(), Options])])
-  export type Spec = z.infer<typeof Spec>
-
-  export type Scope = "global" | "local"
-
-  // Origin keeps the original config provenance attached to a spec.
-  // After multiple config files are merged, callers still need to know which file declared the plugin
-  // and whether it should behave like a global or project-local plugin.
-  export type Origin = {
-    spec: Spec
-    source: string
-    scope: Scope
-  }
+const Options = z.record(z.string(), z.unknown())
+export type Options = z.infer<typeof Options>
 
-  export async function load(dir: string) {
-    const plugins: ConfigPlugin.Spec[] = []
-
-    for (const item of await Glob.scan("{plugin,plugins}/*.{ts,js}", {
-      cwd: dir,
-      absolute: true,
-      dot: true,
-      symlink: true,
-    })) {
-      plugins.push(pathToFileURL(item).href)
-    }
-    return plugins
-  }
+// Spec is the user-config value: either just a plugin identifier, or the identifier plus inline options.
+// It answers "what should we load?" but says nothing about where that value came from.
+export const Spec = z.union([z.string(), z.tuple([z.string(), Options])])
+export type Spec = z.infer<typeof Spec>
 
-  export function pluginSpecifier(plugin: Spec): string {
-    return Array.isArray(plugin) ? plugin[0] : plugin
-  }
+export type Scope = "global" | "local"
+
+// Origin keeps the original config provenance attached to a spec.
+// After multiple config files are merged, callers still need to know which file declared the plugin
+// and whether it should behave like a global or project-local plugin.
+export type Origin = {
+  spec: Spec
+  source: string
+  scope: Scope
+}
+
+export async function load(dir: string) {
+  const plugins: Spec[] = []
 
-  export function pluginOptions(plugin: Spec): Options | undefined {
-    return Array.isArray(plugin) ? plugin[1] : undefined
+  for (const item of await Glob.scan("{plugin,plugins}/*.{ts,js}", {
+    cwd: dir,
+    absolute: true,
+    dot: true,
+    symlink: true,
+  })) {
+    plugins.push(pathToFileURL(item).href)
   }
+  return plugins
+}
+
+export function pluginSpecifier(plugin: Spec): string {
+  return Array.isArray(plugin) ? plugin[0] : plugin
+}
+
+export function pluginOptions(plugin: Spec): Options | undefined {
+  return Array.isArray(plugin) ? plugin[1] : undefined
+}
 
-  // Path-like specs are resolved relative to the config file that declared them so merges later on do not
-  // accidentally reinterpret `./plugin.ts` relative to some other directory.
-  export async function resolvePluginSpec(plugin: Spec, configFilepath: string): Promise<Spec> {
-    const spec = pluginSpecifier(plugin)
-    if (!isPathPluginSpec(spec)) return plugin
+// Path-like specs are resolved relative to the config file that declared them so merges later on do not
+// accidentally reinterpret `./plugin.ts` relative to some other directory.
+export async function resolvePluginSpec(plugin: Spec, configFilepath: string): Promise<Spec> {
+  const spec = pluginSpecifier(plugin)
+  if (!isPathPluginSpec(spec)) return plugin
 
-    const base = path.dirname(configFilepath)
-    const file = (() => {
-      if (spec.startsWith("file://")) return spec
-      if (path.isAbsolute(spec) || /^[A-Za-z]:[\\/]/.test(spec)) return pathToFileURL(spec).href
-      return pathToFileURL(path.resolve(base, spec)).href
-    })()
+  const base = path.dirname(configFilepath)
+  const file = (() => {
+    if (spec.startsWith("file://")) return spec
+    if (path.isAbsolute(spec) || /^[A-Za-z]:[\\/]/.test(spec)) return pathToFileURL(spec).href
+    return pathToFileURL(path.resolve(base, spec)).href
+  })()
 
-    const resolved = await resolvePathPluginTarget(file).catch(() => file)
+  const resolved = await resolvePathPluginTarget(file).catch(() => file)
 
-    if (Array.isArray(plugin)) return [resolved, plugin[1]]
-    return resolved
-  }
+  if (Array.isArray(plugin)) return [resolved, plugin[1]]
+  return resolved
+}
+
+// Dedupe on the load identity (package name for npm specs, exact file URL for local specs), but keep the
+// full Origin so downstream code still knows which config file won and where follow-up writes should go.
+export function deduplicatePluginOrigins(plugins: Origin[]): Origin[] {
+  const seen = new Set<string>()
+  const list: Origin[] = []
 
-  // Dedupe on the load identity (package name for npm specs, exact file URL for local specs), but keep the
-  // full Origin so downstream code still knows which config file won and where follow-up writes should go.
-  export function deduplicatePluginOrigins(plugins: Origin[]): Origin[] {
-    const seen = new Set<string>()
-    const list: Origin[] = []
-
-    for (const plugin of plugins.toReversed()) {
-      const spec = pluginSpecifier(plugin.spec)
-      const name = spec.startsWith("file://") ? spec : parsePluginSpecifier(spec).pkg
-      if (seen.has(name)) continue
-      seen.add(name)
-      list.push(plugin)
-    }
-
-    return list.toReversed()
+  for (const plugin of plugins.toReversed()) {
+    const spec = pluginSpecifier(plugin.spec)
+    const name = spec.startsWith("file://") ? spec : parsePluginSpecifier(spec).pkg
+    if (seen.has(name)) continue
+    seen.add(name)
+    list.push(plugin)
   }
+
+  return list.toReversed()
 }
+
+export * as ConfigPlugin from "./plugin"