diff --git a/src/Detection/Framework.php b/src/Detection/Framework.php index fceaffb..5058e4d 100644 --- a/src/Detection/Framework.php +++ b/src/Detection/Framework.php @@ -39,4 +39,21 @@ abstract public function getInstallCommand(): string; abstract public function getBuildCommand(): string; abstract public function getOutputDirectory(): string; + + /** + * @return array Config files to read for adapter detection, in priority order. + */ + public function getConfigFiles(): array + { + return []; + } + + /** + * Detect the adapter ('ssr' or 'static') from config file content. + * Returns empty string if detection is not possible. + */ + public function getAdapter(string $configContent): string + { + return ''; + } } diff --git a/src/Detection/Framework/Astro.php b/src/Detection/Framework/Astro.php index 6db7fe0..e16b684 100644 --- a/src/Detection/Framework/Astro.php +++ b/src/Detection/Framework/Astro.php @@ -67,4 +67,23 @@ public function getOutputDirectory(): string { return './dist'; } + + /** + * @return array + */ + public function getConfigFiles(): array + { + return ['astro.config.mjs', 'astro.config.js', 'astro.config.ts']; + } + + public function getAdapter(string $configContent): string + { + $stripped = \preg_replace('/(? + */ + public function getConfigFiles(): array + { + return ['package.json']; + } + + public function getAdapter(string $configContent): string + { + return 'ssr'; + } } diff --git a/src/Detection/Framework/SvelteKit.php b/src/Detection/Framework/SvelteKit.php index 0c35be1..331a295 100644 --- a/src/Detection/Framework/SvelteKit.php +++ b/src/Detection/Framework/SvelteKit.php @@ -49,4 +49,19 @@ public function getOutputDirectory(): string { return './build'; } + + /** + * @return array + */ + public function getConfigFiles(): array + { + return ['svelte.config.js', 'svelte.config.mjs', 'svelte.config.ts', 'package.json']; + } + + public function getAdapter(string $configContent): string + { + $stripped = \preg_replace('/(? + */ + public function getConfigFiles(): array + { + return ['vite.config.ts', 'vite.config.js', 'vite.config.mjs']; + } + + public function getAdapter(string $configContent): string + { + $stripped = \preg_replace('/(?assertSame($framework, $detection->getName(), $assertion); } + + public function testTanStackStartAdapterDetection(): void + { + $fw = new TanStackStart(); + + $this->assertSame('ssr', $fw->getAdapter('export default defineConfig({ plugins: [tanstackStart()] })')); + $this->assertSame('static', $fw->getAdapter('export default defineConfig({ plugins: [tanstackStart({ prerender: { routes: [\'/\'] } })] })')); + $this->assertSame('ssr', $fw->getAdapter('export default defineConfig({ plugins: [tanstackStart({ prerender: false })] })')); + $this->assertSame('ssr', $fw->getAdapter('export default defineConfig({ plugins: [tanstackStart({ "prerender": false })] })')); + $this->assertSame('ssr', $fw->getAdapter('// prerender: true' . "\n" . 'export default defineConfig({})')); + $this->assertSame('static', $fw->getAdapter('server: { url: "https://example.com" },' . "\n" . 'prerender: { routes: [\'/\'] }')); + $this->assertNotEmpty($fw->getConfigFiles()); + } + + public function testSvelteKitAdapterDetection(): void + { + $fw = new SvelteKit(); + + $this->assertSame('ssr', $fw->getAdapter('import adapter from \'@sveltejs/adapter-auto\'; export default { kit: { adapter: adapter() } }')); + $this->assertSame('static', $fw->getAdapter('import adapter from \'@sveltejs/adapter-static\'; export default { kit: { adapter: adapter() } }')); + $this->assertSame('static', $fw->getAdapter('{"dependencies":{"@sveltejs/adapter-static":"^3.0.0"}}')); + $this->assertSame('ssr', $fw->getAdapter('// import adapter from \'@sveltejs/adapter-static\'' . "\n" . 'import adapter from \'@sveltejs/adapter-auto\'')); + $this->assertContains('package.json', $fw->getConfigFiles()); + $this->assertNotEmpty($fw->getConfigFiles()); + } + + public function testAstroAdapterDetection(): void + { + $fw = new Astro(); + + $this->assertSame('static', $fw->getAdapter('export default defineConfig({ integrations: [] })')); + $this->assertSame('ssr', $fw->getAdapter('export default defineConfig({ output: \'server\', adapter: node({ mode: \'standalone\' }) })')); + $this->assertSame('ssr', $fw->getAdapter('export default defineConfig({ output: "server" })')); + $this->assertSame('ssr', $fw->getAdapter('export default defineConfig({ output: \'hybrid\' })')); + $this->assertSame('ssr', $fw->getAdapter('export default defineConfig({ output : \'server\' })')); + $this->assertSame('static', $fw->getAdapter('// output: \'server\'' . "\n" . 'export default defineConfig({})')); + $this->assertSame('ssr', $fw->getAdapter('site: "https://example.com",' . "\n" . 'output: "server"')); + $this->assertSame('ssr', $fw->getAdapter('export default defineConfig({ output: `server` })')); + $this->assertSame('ssr', $fw->getAdapter('export default defineConfig({ output: `hybrid` })')); + $this->assertNotEmpty($fw->getConfigFiles()); + } + + public function testRemixAdapterDetection(): void + { + $fw = new Remix(); + + $this->assertSame('ssr', $fw->getAdapter('{"dependencies":{"@remix-run/react":"^2.0.0"}}')); + $this->assertSame('ssr', $fw->getAdapter('{"dependencies":{"@remix-run/serve":"^2.0.0"}}')); + $this->assertSame('ssr', $fw->getAdapter('{"dependencies":{"@remix-run/node":"^2.0.0"}}')); + $this->assertSame('ssr', $fw->getAdapter('')); + $this->assertContains('package.json', $fw->getConfigFiles()); + } }