| 986 | } |
| 987 | |
| 988 | function mockGithubFetch(options: MockGithubFetchOptions): { [Symbol.dispose](): void } { |
| 989 | const original = globalThis.fetch; |
| 990 | globalThis.fetch = vi.fn(async (input: Parameters<typeof fetch>[0], init?: RequestInit) => { |
| 991 | const url = |
| 992 | typeof input === 'string' |
| 993 | ? input |
| 994 | : input instanceof URL |
| 995 | ? input.href |
| 996 | : input.url; |
| 997 | if (/^https:\/\/github\.com\/[^/]+\/[^/]+\/releases\/latest$/.test(url)) { |
| 998 | options.onReleaseLookup?.(); |
| 999 | if (options.releaseTag === undefined) { |
| 1000 | return new Response(null, { status: 404 }); |
| 1001 | } |
| 1002 | const tagUrl = url.replace(/\/releases\/latest$/, `/releases/tag/${options.releaseTag}`); |
| 1003 | return new Response(null, { |
| 1004 | status: 302, |
| 1005 | headers: { location: tagUrl }, |
| 1006 | }); |
| 1007 | } |
| 1008 | if (url.startsWith('https://codeload.github.com/')) { |
| 1009 | // HEAD probe used by the no-release fallback path returns headers only. |
| 1010 | if (init?.method === 'HEAD') { |
| 1011 | return new Response(null, { status: 200 }); |
| 1012 | } |
| 1013 | return new Response(options.tarball, { status: 200 }); |
| 1014 | } |
| 1015 | throw new Error(`mockGithubFetch: unexpected url ${url}`); |
| 1016 | }) as typeof fetch; |
| 1017 | return { |
| 1018 | [Symbol.dispose]() { |
| 1019 | globalThis.fetch = original; |
| 1020 | }, |
| 1021 | }; |
| 1022 | } |
| 1023 | |
| 1024 | async function createZipBuffer(entries: Array<{ name: string; data: string | Buffer }>): Promise<Buffer> { |
| 1025 | return new Promise((resolve, reject) => { |