( importPath: string, ws: WorkspacePackages )
| 205 | * name matches. |
| 206 | */ |
| 207 | export function resolveWorkspaceImport( |
| 208 | importPath: string, |
| 209 | ws: WorkspacePackages |
| 210 | ): string | null { |
| 211 | // Longest matching package name wins, so `@scope/ui/core` prefers a |
| 212 | // `@scope/ui/core` package over a `@scope/ui` one when both exist. |
| 213 | let bestName: string | null = null; |
| 214 | for (const name of ws.byName.keys()) { |
| 215 | if (importPath === name || importPath.startsWith(name + '/')) { |
| 216 | if (!bestName || name.length > bestName.length) bestName = name; |
| 217 | } |
| 218 | } |
| 219 | if (!bestName) return null; |
| 220 | const dir = ws.byName.get(bestName)!; |
| 221 | const subpath = importPath.slice(bestName.length); // '' or '/widgets' |
| 222 | // A bare member import resolves straight to the member's declared entry |
| 223 | // file when the manifest names one (ohpm `main`) — the caller's exact-path |
| 224 | // check hits it without extension/index guessing. |
| 225 | if (!subpath) { |
| 226 | const entry = ws.entryByName?.get(bestName); |
| 227 | if (entry) return entry; |
| 228 | } |
| 229 | return (dir + subpath).replace(/\/{2,}/g, '/'); |
| 230 | } |
| 231 | |
| 232 | /** Read workspace glob patterns from package.json + pnpm-workspace.yaml. */ |
| 233 | function readWorkspaceGlobs(projectRoot: string): string[] { |
no test coverage detected