(
url: string,
ref?: string,
opts: {
token?: string;
maxBytes?: number;
fetchImpl?: typeof fetch;
parseLimits?: Partial<ParsePackLimits>;
allowPrivateHosts?: boolean;
} = {},
)
| 21 | } |
| 22 | |
| 23 | export async function handFetch( |
| 24 | url: string, |
| 25 | ref?: string, |
| 26 | opts: { |
| 27 | token?: string; |
| 28 | maxBytes?: number; |
| 29 | fetchImpl?: typeof fetch; |
| 30 | parseLimits?: Partial<ParsePackLimits>; |
| 31 | allowPrivateHosts?: boolean; |
| 32 | } = {}, |
| 33 | ): Promise<FetchResult> { |
| 34 | const t0 = Date.now(); |
| 35 | try { |
| 36 | const host = new URL(url).host; |
| 37 | const auth: AuthRecipe = authForHost(host, opts.token); |
| 38 | const refs = await checkRefs(url, auth, opts.fetchImpl, { |
| 39 | allowPrivateHosts: opts.allowPrivateHosts, |
| 40 | }); |
| 41 | const { sha, resolvedRef } = resolveWant(refs.adv, ref); |
| 42 | |
| 43 | const up = await uploadPack(url, sha, { |
| 44 | auth, |
| 45 | fetchImpl: opts.fetchImpl, |
| 46 | maxBytes: opts.maxBytes, |
| 47 | allowPrivateHosts: opts.allowPrivateHosts, |
| 48 | }); |
| 49 | if (up.truncated) { |
| 50 | return { |
| 51 | ok: false, |
| 52 | sha, |
| 53 | resolvedRef, |
| 54 | packBytes: up.packBytes.length, |
| 55 | refsMs: refs.wallMs, |
| 56 | fetchMs: up.wallMs, |
| 57 | truncated: true, |
| 58 | wallMs: Date.now() - t0, |
| 59 | error: `byte cap hit at ${up.capUsed} bytes`, |
| 60 | }; |
| 61 | } |
| 62 | |
| 63 | const tp = Date.now(); |
| 64 | const parsed = await parsePack(up.packBytes, { limits: opts.parseLimits }); |
| 65 | const files = walkTree(parsed, sha); |
| 66 | const parseMs = Date.now() - tp; |
| 67 | |
| 68 | let totalBytes = 0; |
| 69 | for (const f of files) totalBytes += f.bytes.length; |
| 70 | |
| 71 | return { |
| 72 | ok: true, |
| 73 | sha, |
| 74 | resolvedRef, |
| 75 | fileCount: files.length, |
| 76 | totalBytes, |
| 77 | packBytes: up.packBytes.length, |
| 78 | refsMs: refs.wallMs, |
| 79 | fetchMs: up.wallMs, |
| 80 | parseMs, |
no test coverage detected