diff --git a/api/index.mjs b/api/index.mjs new file mode 100644 index 0000000..baa3e05 --- /dev/null +++ b/api/index.mjs @@ -0,0 +1,7 @@ +import { getRuntime } from "../apps/lab-guide/cloud/runtime.mjs"; + +export default { + fetch(request) { + return getRuntime().fetch(request); + }, +}; diff --git a/tests/repository-contract.test.mjs b/tests/repository-contract.test.mjs index 865d6dc..19bf954 100644 --- a/tests/repository-contract.test.mjs +++ b/tests/repository-contract.test.mjs @@ -63,3 +63,18 @@ test("implementation roots exist", () => { assert.equal(existsSync(resolve(root, path)), true, `${path} is missing`); } }); + +test("Vercel origin exposes only the ExamServer lab namespace", () => { + const config = JSON.parse(read("vercel.json")); + + assert.equal(config.outputDirectory, "apps/lab-guide/dist/client"); + assert.deepEqual( + config.rewrites.map(({ source }) => source), + ["/api/lab/:path*", "/lab", "/lab/:path*"], + ); + assert.equal( + config.redirects[0].destination, + "https://exam-server-one.vercel.app/lab", + ); + assert.equal(existsSync(resolve(root, "api/index.mjs")), true); +}); diff --git a/vercel.json b/vercel.json new file mode 100644 index 0000000..7ce32d6 --- /dev/null +++ b/vercel.json @@ -0,0 +1,54 @@ +{ + "$schema": "https://openapi.vercel.sh/vercel.json", + "installCommand": "npm ci --prefix apps/lab-guide", + "buildCommand": "npm --prefix apps/lab-guide run build", + "outputDirectory": "apps/lab-guide/dist/client", + "headers": [ + { + "source": "/(.*)", + "headers": [ + { + "key": "Content-Security-Policy", + "value": "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'self'" + }, + { + "key": "Permissions-Policy", + "value": "camera=(), microphone=(), geolocation=()" + }, + { + "key": "Referrer-Policy", + "value": "no-referrer" + }, + { + "key": "X-Content-Type-Options", + "value": "nosniff" + }, + { + "key": "X-Frame-Options", + "value": "DENY" + } + ] + } + ], + "rewrites": [ + { + "source": "/api/lab/:path*", + "destination": "/api?__route=:path*" + }, + { + "source": "/lab", + "destination": "/index.html" + }, + { + "source": "/lab/:path*", + "destination": "/:path*" + } + ], + "redirects": [ + { + "source": "/", + "destination": "https://exam-server-one.vercel.app/lab", + "permanent": false + } + ] +}