MCPcopy Create free account
hub / github.com/vercel/vercel / hashes

Function hashes

packages/client/src/utils/hashes.ts:69–120  ·  view source on GitHub ↗
(
  files: string[],
  map = new Map<string | undefined, DeploymentFile>()
)

Source from the content-addressed store, hash-verified

67 * @return Map of hash digest to file object
68 */
69export async function hashes(
70 files: string[],
71 map = new Map<string | undefined, DeploymentFile>()
72): Promise<FilesMap> {
73 const semaphore = new Sema(100);
74
75 await Promise.all(
76 files.map(async (name: string): Promise<void> => {
77 await semaphore.acquire();
78
79 const stat = await fs.lstat(name);
80 const mode = stat.mode;
81
82 let data: Buffer | undefined;
83 let size: number | undefined;
84 const isDirectory = stat.isDirectory();
85
86 let h: string | undefined;
87
88 if (!isDirectory) {
89 if (stat.isSymbolicLink()) {
90 const link = await fs.readlink(name);
91 data = Buffer.from(link, 'utf8');
92 size = data.length;
93 h = hash(data);
94 } else if (stat.size > MAX_BUFFER_FILE_SIZE) {
95 // Too large to read into a single Buffer; hash by streaming and leave
96 // `data` undefined so the upload streams it from disk as well.
97 size = stat.size;
98 h = await hashFile(name);
99 } else {
100 data = await fs.readFile(name);
101 size = data.length;
102 h = hash(data);
103 }
104 }
105
106 const entry = map.get(h);
107
108 if (entry) {
109 const names = new Set(entry.names);
110 names.add(name);
111 entry.names = [...names];
112 } else {
113 map.set(h, { names: [name], data, mode, size });
114 }
115
116 semaphore.release();
117 })
118 );
119 return map;
120}

Callers 3

continueDeploymentFunction · 0.90
collectDeploymentFilesFunction · 0.90

Calls 8

releaseMethod · 0.80
hashFunction · 0.70
hashFileFunction · 0.70
getMethod · 0.65
isDirectoryMethod · 0.45
isSymbolicLinkMethod · 0.45
addMethod · 0.45
setMethod · 0.45

Tested by

no test coverage detected