@@ -12,6 +12,15 @@ const defaultServerBuildPath = path.join(
1212 'server' ,
1313 'index.js' ,
1414)
15+ const defaultServerRuntimePath = path . join (
16+ here ,
17+ 'node_modules' ,
18+ '@epic-web' ,
19+ 'workshop-app' ,
20+ 'dist' ,
21+ 'server' ,
22+ 'index.js' ,
23+ )
1524
1625const notFoundActionFunctionName = 'action$splatNotFound'
1726const notFoundActionFunction = `async function ${ notFoundActionFunctionName } () {
@@ -50,6 +59,21 @@ const routeManifestNeedle =
5059const patchedRouteManifestNeedle =
5160 '"routes/$": { "id": "routes/$", "parentId": "root", "path": "*", "index": void 0, "caseSensitive": void 0, "hasAction": true,'
5261
62+ const repeatedSlashMiddleware = `app.use((req, res, next) => {
63+ const requestPath = req.originalUrl.split("?")[0];
64+ if (req.method !== "GET" && req.method !== "HEAD" && req.method !== "OPTIONS" && /^\\/{2,}$/.test(requestPath)) {
65+ res.status(404).send("Not found");
66+ return;
67+ }
68+ next();
69+ });
70+ `
71+
72+ const requestContextMiddlewareNeedle =
73+ 'app.use((_req, _res, next) => requestContext.run({}, next));\n'
74+
75+ const patchedRequestContextMiddlewareNeedle = `${ requestContextMiddlewareNeedle } ${ repeatedSlashMiddleware } `
76+
5377export function patchWorkshopAppServerBuild ( source ) {
5478 const hasActionFunction = source . includes (
5579 `async function ${ notFoundActionFunctionName } ()` ,
@@ -111,20 +135,57 @@ export function patchWorkshopAppServerBuild(source) {
111135 }
112136}
113137
138+ export function patchWorkshopAppServerRuntime ( source ) {
139+ if ( source . includes ( repeatedSlashMiddleware ) ) {
140+ return { patched : false , source }
141+ }
142+
143+ if ( ! source . includes ( requestContextMiddlewareNeedle ) ) {
144+ throw new Error (
145+ 'Could not find the workshop-app request context middleware to patch.' ,
146+ )
147+ }
148+
149+ return {
150+ patched : true ,
151+ source : source . replace (
152+ requestContextMiddlewareNeedle ,
153+ patchedRequestContextMiddlewareNeedle ,
154+ ) ,
155+ }
156+ }
157+
114158export async function patchWorkshopApp ( {
115159 serverBuildPath = defaultServerBuildPath ,
160+ serverRuntimePath = defaultServerRuntimePath ,
116161} = { } ) {
117- const source = await fs . readFile ( serverBuildPath , 'utf8' )
118- const result = patchWorkshopAppServerBuild ( source )
119-
120- if ( result . patched ) {
121- await fs . writeFile ( serverBuildPath , result . source )
162+ const [ serverBuildSource , serverRuntimeSource ] = await Promise . all ( [
163+ fs . readFile ( serverBuildPath , 'utf8' ) ,
164+ fs . readFile ( serverRuntimePath , 'utf8' ) ,
165+ ] )
166+ const serverBuildResult = patchWorkshopAppServerBuild ( serverBuildSource )
167+ const serverRuntimeResult = patchWorkshopAppServerRuntime ( serverRuntimeSource )
168+
169+ await Promise . all ( [
170+ serverBuildResult . patched
171+ ? fs . writeFile ( serverBuildPath , serverBuildResult . source )
172+ : null ,
173+ serverRuntimeResult . patched
174+ ? fs . writeFile ( serverRuntimePath , serverRuntimeResult . source )
175+ : null ,
176+ ] )
177+
178+ if ( serverBuildResult . patched || serverRuntimeResult . patched ) {
122179 console . log (
123180 'Patched @epic-web/workshop-app splat route to return a normal 404 for POST scanner traffic.' ,
124181 )
125182 }
126183
127- return result
184+ return {
185+ patched : serverBuildResult . patched || serverRuntimeResult . patched ,
186+ serverBuild : serverBuildResult ,
187+ serverRuntime : serverRuntimeResult ,
188+ }
128189}
129190
130191if ( import . meta. url === pathToFileURL ( process . argv [ 1 ] ) . href ) {
0 commit comments