(options: ExecutorVitePluginOptions = {})
| 81 | } |
| 82 | |
| 83 | export default function executorVitePlugin(options: ExecutorVitePluginOptions = {}): Plugin { |
| 84 | let projectRoot: string = process.cwd(); |
| 85 | let resolvedConfigPath: string | null = null; |
| 86 | let resolvedJsoncPath: string | null = null; |
| 87 | let cachedSource: string | null = null; |
| 88 | |
| 89 | const resolveConfigPath = (): string | null => { |
| 90 | if (resolvedConfigPath) return resolvedConfigPath; |
| 91 | const candidates = options.configPath ? [options.configPath] : DEFAULT_CONFIG_CANDIDATES; |
| 92 | for (const candidate of candidates) { |
| 93 | const abs = isAbsolute(candidate) ? candidate : resolvePath(projectRoot, candidate); |
| 94 | if (existsSync(abs)) { |
| 95 | resolvedConfigPath = abs; |
| 96 | return abs; |
| 97 | } |
| 98 | } |
| 99 | return null; |
| 100 | }; |
| 101 | |
| 102 | const resolveJsoncPath = (): string | null => { |
| 103 | if (resolvedJsoncPath) return resolvedJsoncPath; |
| 104 | const candidates = options.jsoncPath ? [options.jsoncPath] : DEFAULT_JSONC_CANDIDATES; |
| 105 | for (const candidate of candidates) { |
| 106 | const abs = isAbsolute(candidate) ? candidate : resolvePath(projectRoot, candidate); |
| 107 | if (existsSync(abs)) { |
| 108 | resolvedJsoncPath = abs; |
| 109 | return abs; |
| 110 | } |
| 111 | } |
| 112 | return null; |
| 113 | }; |
| 114 | |
| 115 | const loadVirtualSource = async (): Promise<string> => { |
| 116 | if (cachedSource !== null) return cachedSource; |
| 117 | |
| 118 | const configPath = resolveConfigPath(); |
| 119 | const jsoncPath = resolveJsoncPath(); |
| 120 | const fromDir = configPath ? dirname(configPath) : projectRoot; |
| 121 | |
| 122 | // Collect plugin entries in priority order: static config first, |
| 123 | // jsonc second. De-duplicate by package name — if both list the |
| 124 | // same plugin, only one import is emitted. (Static wins for the |
| 125 | // ordering of `plugins` array, which matters for nav order.) |
| 126 | // |
| 127 | // `clientConfig` only flows in via the static config path: it |
| 128 | // lives on the runtime `PluginSpec` returned by |
| 129 | // `definePlugin(...)`, which is only available when we jiti-load |
| 130 | // the TS module. The jsonc path carries package names only. |
| 131 | const entries: Array<{ readonly pkg: string; readonly clientConfig?: unknown }> = []; |
| 132 | const seen = new Set<string>(); |
| 133 | |
| 134 | if (configPath) { |
| 135 | // jiti is a dev dep of consumers; importing dynamically lets the |
| 136 | // plugin be lazy-loaded and avoids a hard requirement when the |
| 137 | // host doesn't actually use plugins yet. |
| 138 | const { createJiti } = await import("jiti"); |
| 139 | const jiti = createJiti(pathToFileURL(configPath).href, { |
| 140 | interopDefault: true, |
no outgoing calls
no test coverage detected