diff --git a/src/Phaseolies/Console/Commands/FrontendInstallCommand.php b/src/Phaseolies/Console/Commands/FrontendInstallCommand.php index d6b0765..bed3439 100644 --- a/src/Phaseolies/Console/Commands/FrontendInstallCommand.php +++ b/src/Phaseolies/Console/Commands/FrontendInstallCommand.php @@ -483,9 +483,12 @@ protected function bootstrapFile(string $cssStack, bool $typescript): string ? "import 'bootstrap/dist/js/bootstrap.bundle.min.js';\n" : ''; - return $this->renderFrontendStub('entries/bootstrap.stub', [ - 'bootstrapVendorImport' => $bootstrapVendorImport, - ]); + return $this->renderFrontendStub( + 'entries/' . ($typescript ? 'bootstrap.ts.stub' : 'bootstrap.js.stub'), + [ + 'bootstrapVendorImport' => $bootstrapVendorImport, + ] + ); } /** diff --git a/src/Phaseolies/Console/Commands/stubs/frontend/entries/bootstrap.js.stub b/src/Phaseolies/Console/Commands/stubs/frontend/entries/bootstrap.js.stub new file mode 100644 index 0000000..df24346 --- /dev/null +++ b/src/Phaseolies/Console/Commands/stubs/frontend/entries/bootstrap.js.stub @@ -0,0 +1,9 @@ +{{ bootstrapVendorImport }}const csrfToken = document + .querySelector('meta[name="csrf-token"]') + ?.getAttribute('content'); + +window.__DOPPAR_FRONTEND__ = { + ...(window.__DOPPAR_FRONTEND__ ?? {}), + csrfToken: csrfToken ?? null, + headers: csrfToken ? { 'X-CSRF-TOKEN': csrfToken } : {}, +}; diff --git a/src/Phaseolies/Console/Commands/stubs/frontend/entries/bootstrap.stub b/src/Phaseolies/Console/Commands/stubs/frontend/entries/bootstrap.ts.stub similarity index 100% rename from src/Phaseolies/Console/Commands/stubs/frontend/entries/bootstrap.stub rename to src/Phaseolies/Console/Commands/stubs/frontend/entries/bootstrap.ts.stub diff --git a/tests/Console/FrontendInstallCommandTest.php b/tests/Console/FrontendInstallCommandTest.php index 3d29c0d..e7ce21a 100644 --- a/tests/Console/FrontendInstallCommandTest.php +++ b/tests/Console/FrontendInstallCommandTest.php @@ -105,6 +105,20 @@ public function testClientBootstrapExposesCsrfHeaderFromMetaToken(): void $this->assertStringNotContainsString('XMLHttpRequest.prototype', $bootstrap); $this->assertStringNotContainsString('X-Requested-With', $bootstrap); $this->assertStringContainsString("import 'bootstrap/dist/js/bootstrap.bundle.min.js';", $bootstrap); + $this->assertStringContainsString('declare global', $bootstrap); + } + + public function testJavascriptBootstrapStubAvoidsTypescriptOnlySyntax(): void + { + $command = new FrontendInstallCommand(); + $method = new \ReflectionMethod($command, 'bootstrapFile'); + + $bootstrap = $method->invoke($command, 'bootstrap', false); + + $this->assertStringContainsString("meta[name=\"csrf-token\"]", $bootstrap); + $this->assertStringContainsString("headers: csrfToken ? { 'X-CSRF-TOKEN': csrfToken } : {}", $bootstrap); + $this->assertStringContainsString("import 'bootstrap/dist/js/bootstrap.bundle.min.js';", $bootstrap); + $this->assertStringNotContainsString('declare global', $bootstrap); } public function testVuePackageJsonUsesViteSevenCompatiblePluginVersion(): void