( req: IncomingMessage, socket: Duplex, head: Buffer, workspaceId: string, target: NormalizedPreviewTarget, )
| 414 | const head = /<head(?:\s[^>]*)?>/i; |
| 415 | if (head.test(body)) return body.replace(head, (match) => `${match}${script}`); |
| 416 | return `${script}${body}`; |
| 417 | } |
| 418 | |
| 419 | export function rewritePreviewBody( |
| 420 | body: string, |
| 421 | workspaceId: string, |
| 422 | contentType?: string | string[], |
| 423 | previewToken?: string | null, |
| 424 | target?: NormalizedPreviewTarget, |
| 425 | ): string { |
| 426 | const prefix = buildPreviewPathPrefix(workspaceId, previewToken); |
| 427 | const value = Array.isArray(contentType) ? contentType.join(';') : contentType ?? ''; |
| 428 | const lower = value.toLowerCase(); |
| 429 | |
| 430 | let next = body; |
| 431 | |
| 432 | if (lower.includes('text/html')) { |
| 433 | next = next |
| 434 | .replace(/(\s(?:src|href|action|poster|data|content)=["'])\/(?!\/|view\/)([^"']*)/gi, `$1${prefix}/$2`) |
| 435 | .replace(/(\s(?:srcset)=["'])([^"']*)(["'])/gi, (_match, before: string, srcset: string, after: string) => { |
| 436 | const rewritten = srcset.replace(/(^|,\s*)\/(?!\/|view\/)([^\s,]+)/g, `$1${prefix}/$2`); |
| 437 | return `${before}${rewritten}${after}`; |
| 438 | }); |
| 439 | } |
| 440 | |
| 441 | if (lower.includes('text/css') || lower.includes('text/html')) { |
| 442 | next = next.replace(/url\((['"]?)\/(?!\/|view\/)([^)'"]+)\1\)/g, `url($1${prefix}/$2$1)`); |
| 443 | } |
| 444 | |
| 445 | if (lower.includes('javascript') || lower.includes('ecmascript') || lower.includes('text/html')) { |
| 446 | next = rewriteJavaScriptRouterBasenameDefaults(next, prefix); |
| 447 | next = rewriteJavaScriptPathLiterals(next, prefix); |
| 448 | } |
| 449 | |
| 450 | if (lower.includes('text/html') && target) { |
| 451 | next = injectPreviewRuntimeBridge(next, prefix, target); |
| 452 | } |
| 453 | |
| 454 | return next; |
| 455 | } |
| 456 | |
| 457 | function requestBodyBuffer(request: FastifyRequest): Buffer | null { |
| 458 | const method = request.method.toUpperCase(); |
| 459 | if (method === 'GET' || method === 'HEAD') return null; |
| 460 | |
| 461 | const body = request.body; |
| 462 | if (body === undefined || body === null) return null; |
| 463 | if (Buffer.isBuffer(body)) return body; |
| 464 | if (typeof body === 'string') return Buffer.from(body); |
| 465 | return Buffer.from(JSON.stringify(body)); |
| 466 | } |
| 467 | |
| 468 | async function proxyHttpRequest( |
| 469 | request: FastifyRequest, |
| 470 | response: ServerResponse, |
| 471 | workspaceId: string, |
| 472 | target: NormalizedPreviewTarget, |
| 473 | previewToken?: string | null, |
no test coverage detected