You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
	
	
		
			132 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
		
		
			
		
	
	
			132 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			JavaScript
		
	
| 
											9 months ago
										 | "use strict"; | ||
|  | Object.defineProperty(exports, "__esModule", { | ||
|  |     value: true | ||
|  | }); | ||
|  | 0 && (module.exports = { | ||
|  |     reader: null, | ||
|  |     handleFetch: null, | ||
|  |     interceptFetch: null | ||
|  | }); | ||
|  | function _export(target, all) { | ||
|  |     for(var name in all)Object.defineProperty(target, name, { | ||
|  |         enumerable: true, | ||
|  |         get: all[name] | ||
|  |     }); | ||
|  | } | ||
|  | _export(exports, { | ||
|  |     reader: function() { | ||
|  |         return reader; | ||
|  |     }, | ||
|  |     handleFetch: function() { | ||
|  |         return handleFetch; | ||
|  |     }, | ||
|  |     interceptFetch: function() { | ||
|  |         return interceptFetch; | ||
|  |     } | ||
|  | }); | ||
|  | const _context = require("./context"); | ||
|  | const reader = { | ||
|  |     url (req) { | ||
|  |         return req.url; | ||
|  |     }, | ||
|  |     header (req, name) { | ||
|  |         return req.headers.get(name); | ||
|  |     } | ||
|  | }; | ||
|  | function getTestStack() { | ||
|  |     let stack = (new Error().stack ?? "").split("\n"); | ||
|  |     // Skip the first line and find first non-empty line.
 | ||
|  |     for(let i = 1; i < stack.length; i++){ | ||
|  |         if (stack[i].length > 0) { | ||
|  |             stack = stack.slice(i); | ||
|  |             break; | ||
|  |         } | ||
|  |     } | ||
|  |     // Filter out franmework lines.
 | ||
|  |     stack = stack.filter((f)=>!f.includes("/next/dist/")); | ||
|  |     // At most 5 lines.
 | ||
|  |     stack = stack.slice(0, 5); | ||
|  |     // Cleanup some internal info and trim.
 | ||
|  |     stack = stack.map((s)=>s.replace("webpack-internal:///(rsc)/", "").trim()); | ||
|  |     return stack.join("    "); | ||
|  | } | ||
|  | async function buildProxyRequest(testData, request) { | ||
|  |     const { url, method, headers, body, cache, credentials, integrity, mode, redirect, referrer, referrerPolicy } = request; | ||
|  |     return { | ||
|  |         testData, | ||
|  |         api: "fetch", | ||
|  |         request: { | ||
|  |             url, | ||
|  |             method, | ||
|  |             headers: [ | ||
|  |                 ...Array.from(headers), | ||
|  |                 [ | ||
|  |                     "next-test-stack", | ||
|  |                     getTestStack() | ||
|  |                 ] | ||
|  |             ], | ||
|  |             body: body ? Buffer.from(await request.arrayBuffer()).toString("base64") : null, | ||
|  |             cache, | ||
|  |             credentials, | ||
|  |             integrity, | ||
|  |             mode, | ||
|  |             redirect, | ||
|  |             referrer, | ||
|  |             referrerPolicy | ||
|  |         } | ||
|  |     }; | ||
|  | } | ||
|  | function buildResponse(proxyResponse) { | ||
|  |     const { status, headers, body } = proxyResponse.response; | ||
|  |     return new Response(body ? Buffer.from(body, "base64") : null, { | ||
|  |         status, | ||
|  |         headers: new Headers(headers) | ||
|  |     }); | ||
|  | } | ||
|  | async function handleFetch(originalFetch, request) { | ||
|  |     const testInfo = (0, _context.getTestReqInfo)(request, reader); | ||
|  |     if (!testInfo) { | ||
|  |         throw new Error(`No test info for ${request.method} ${request.url}`); | ||
|  |     } | ||
|  |     const { testData, proxyPort } = testInfo; | ||
|  |     const proxyRequest = await buildProxyRequest(testData, request); | ||
|  |     const resp = await originalFetch(`http://localhost:${proxyPort}`, { | ||
|  |         method: "POST", | ||
|  |         body: JSON.stringify(proxyRequest), | ||
|  |         next: { | ||
|  |             // @ts-ignore
 | ||
|  |             internal: true | ||
|  |         } | ||
|  |     }); | ||
|  |     if (!resp.ok) { | ||
|  |         throw new Error(`Proxy request failed: ${resp.status}`); | ||
|  |     } | ||
|  |     const proxyResponse = await resp.json(); | ||
|  |     const { api } = proxyResponse; | ||
|  |     switch(api){ | ||
|  |         case "continue": | ||
|  |             return originalFetch(request); | ||
|  |         case "abort": | ||
|  |         case "unhandled": | ||
|  |             throw new Error(`Proxy request aborted [${request.method} ${request.url}]`); | ||
|  |         default: | ||
|  |             break; | ||
|  |     } | ||
|  |     return buildResponse(proxyResponse); | ||
|  | } | ||
|  | function interceptFetch(originalFetch) { | ||
|  |     global.fetch = function testFetch(input, init) { | ||
|  |         var _init_next; | ||
|  |         // Passthrough internal requests.
 | ||
|  |         // @ts-ignore
 | ||
|  |         if (init == null ? void 0 : (_init_next = init.next) == null ? void 0 : _init_next.internal) { | ||
|  |             return originalFetch(input, init); | ||
|  |         } | ||
|  |         return handleFetch(originalFetch, new Request(input, init)); | ||
|  |     }; | ||
|  |     return ()=>{ | ||
|  |         global.fetch = originalFetch; | ||
|  |     }; | ||
|  | } | ||
|  | 
 | ||
|  | //# sourceMappingURL=fetch.js.map
 |