UNPKG

2.22 kBJavaScriptView Raw
1// @flow strict-local
2import type {Blob, FilePath} from '@parcel/types';
3import type {FileSystem} from '@parcel/fs';
4import type {AssetRequestDesc} from './types';
5
6import {md5FromReadableStream, md5FromString, TapStream} from '@parcel/utils';
7import path from 'path';
8
9const NODE_MODULES = `${path.sep}node_modules${path.sep}`;
10
11const BUFFER_LIMIT = 5000000; // 5mb
12
13export default async function summarizeRequest(
14 fs: FileSystem,
15 req: AssetRequestDesc,
16): Promise<{|content: Blob, hash: string, size: number, isSource: boolean|}> {
17 let [{content, hash, size}, isSource] = await Promise.all([
18 summarizeDiskRequest(fs, req),
19 isFilePathSource(fs, req.filePath),
20 ]);
21 return {content, hash, size, isSource};
22}
23
24async function isFilePathSource(fs: FileSystem, filePath: FilePath) {
25 return (
26 !filePath.includes(NODE_MODULES) ||
27 (await fs.realpath(filePath)) !== filePath
28 );
29}
30
31async function summarizeDiskRequest(
32 fs: FileSystem,
33 req: AssetRequestDesc,
34): Promise<{|content: Blob, hash: string, size: number|}> {
35 let code = req.code;
36 let content: Blob;
37 let hash: string;
38 let size: number;
39 if (code == null) {
40 // As an optimization for the common case of source code, while we read in
41 // data to compute its md5 and size, buffer its contents in memory.
42 // This avoids reading the data now, and then again during transformation.
43 // If it exceeds BUFFER_LIMIT, throw it out and replace it with a stream to
44 // lazily read it at a later point.
45 content = Buffer.from([]);
46 size = 0;
47 hash = await md5FromReadableStream(
48 fs.createReadStream(req.filePath).pipe(
49 new TapStream(buf => {
50 size += buf.length;
51 if (content instanceof Buffer) {
52 if (size > BUFFER_LIMIT) {
53 // if buffering this content would put this over BUFFER_LIMIT, replace
54 // it with a stream
55 content = fs.createReadStream(req.filePath);
56 } else {
57 content = Buffer.concat([content, buf]);
58 }
59 }
60 }),
61 ),
62 );
63 } else {
64 content = code;
65 hash = md5FromString(code);
66 size = Buffer.from(code).length;
67 }
68
69 return {content, hash, size};
70}