import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import fs from 'node:fs/promises'; import path from 'node:path'; import os from 'node:os'; import { extractNodeWorkspaceLinks } from '../../../src/core/group/extractors/node-workspace-extractor.js'; describe('NodeWorkspaceExtractor', () => { let tmpDir: string; beforeEach(async () => { tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'gitnexus-node-ws-')); }); afterEach(async () => { await fs.rm(tmpDir, { recursive: true, force: true }); }); async function writeFile(relPath: string, content: string) { const absPath = path.join(tmpDir, relPath); await fs.mkdir(path.dirname(absPath), { recursive: true }); await fs.writeFile(absPath, content, 'utf-8'); } it('discovers cross-package ES imports', async () => { await writeFile( 'pkg-a/package.json', JSON.stringify({ name: '@myorg/shared', version: '1.0.0' }), ); await writeFile('pkg-a/src/index.ts', 'export class Config {}\nexport class Logger {}\n'); await writeFile( 'pkg-b/package.json', JSON.stringify({ name: '@myorg/api', version: '1.0.0', dependencies: { '@myorg/shared': 'workspace:*' }, }), ); await writeFile( 'pkg-b/src/server.ts', "import { Config } from '@myorg/shared';\nconst c = new Config();\n", ); const repos = { 'libs/shared': '@myorg/shared', 'services/api': '@myorg/api', }; const repoPaths = new Map([ ['libs/shared', path.join(tmpDir, 'pkg-a')], ['services/api', path.join(tmpDir, 'pkg-b')], ]); const result = await extractNodeWorkspaceLinks(repos, repoPaths); expect(result.links).toHaveLength(1); expect(result.links[0]).toEqual({ from: 'libs/shared', to: 'services/api', type: 'custom', contract: '@myorg/shared::Config', role: 'provider', }); }); it('handles default imports (PascalCase)', async () => { await writeFile( 'ui-lib/package.json', JSON.stringify({ name: 'ui-components', version: '1.0.0' }), ); await writeFile('ui-lib/src/index.ts', 'export default class Button {}\n'); await writeFile( 'app/package.json', JSON.stringify({ name: 'web-app', version: '1.0.0', dependencies: { 'ui-components': '^1.0.0' }, }), ); await writeFile( 'app/src/page.tsx', "import Button from 'ui-components';\nexport default function Page() { return