@metamask-previews/foundryup 1.0.1-preview-5ae42f53d → 1.0.1-preview-e2b065b23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/extract.cjs CHANGED
@@ -111,6 +111,9 @@ async function extractFromTar(url, binaries, dir, checksumAlgorithm) {
111
111
  const downloads = [];
112
112
  await (0, promises_2.pipeline)((0, download_js_1.startDownload)(url), (0, tar_1.extract)({
113
113
  cwd: dir,
114
+ // @ts-expect-error: Types here broke in `tar@7.5.12`, but it appears to
115
+ // work fine as-is.
116
+ // See: https://github.com/isaacs/node-tar/issues/459
114
117
  transform: (entry) => {
115
118
  const absolutePath = entry.absolute;
116
119
  if (!absolutePath) {
@@ -1 +1 @@
1
- {"version":3,"file":"extract.cjs","sourceRoot":"","sources":["../src/extract.ts"],"names":[],"mappings":"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","sourcesContent":["import { Minipass } from 'minipass';\nimport { ok } from 'node:assert/strict';\nimport { createHash } from 'node:crypto';\nimport { createWriteStream } from 'node:fs';\nimport { rename, mkdir, rm } from 'node:fs/promises';\nimport { Agent as HttpAgent } from 'node:http';\nimport { Agent as HttpsAgent } from 'node:https';\nimport { join, basename, extname, relative } from 'node:path';\nimport { pipeline } from 'node:stream/promises';\nimport { extract as extractTar } from 'tar';\nimport { Open } from 'unzipper';\nimport type { Source, Entry } from 'unzipper';\n\nimport { startDownload } from './download.js';\nimport { Extension } from './types.js';\nimport type { Binary } from './types.js';\nimport { say } from './utils.js';\n\n/**\n * Extracts the binaries from the given URL and writes them to the destination.\n *\n * @param url - The URL of the archive to extract the binaries from\n * @param binaries - The list of binaries to extract\n * @param dir - The destination directory\n * @param checksums - The checksums to verify the binaries against\n * @returns The list of binaries extracted\n */\n\n/**\n * Extracts the binaries from the given URL and writes them to the destination.\n *\n * @param url - The URL of the archive to extract the binaries from\n * @param binaries - The list of binaries to extract\n * @param dir - The destination directory\n * @param checksums - The checksums to verify the binaries against\n * @returns The list of binaries extracted\n */\nexport async function extractFrom(\n url: URL,\n binaries: Binary[],\n dir: string,\n checksums: { algorithm: string; binaries: Record<Binary, string> } | null,\n) {\n const extract = url.pathname.toLowerCase().endsWith(Extension.Tar)\n ? extractFromTar\n : extractFromZip;\n // write all files to a temporary directory first, then rename to the final\n // destination to avoid accidental partial extraction. We don't use\n // `os.tmpdir` for this because `rename` will fail if the directories are on\n // different file systems.\n const tempDir = `${dir}.downloading`;\n const rmOpts = { recursive: true, maxRetries: 3, force: true };\n try {\n // clean up any previous in-progress downloads\n await rm(tempDir, rmOpts);\n // make the temporary directory to extract the binaries to\n await mkdir(tempDir, { recursive: true });\n const downloads = await extract(\n url,\n binaries,\n tempDir,\n checksums?.algorithm,\n );\n ok(downloads.length === binaries.length, 'Failed to extract all binaries');\n\n const paths: string[] = [];\n for (const { path, binary, checksum } of downloads) {\n if (checksums) {\n say(`verifying checksum for ${binary}`);\n const expected = checksums.binaries[binary];\n if (checksum === expected) {\n say(`checksum verified for ${binary}`);\n } else {\n throw new Error(\n `checksum mismatch for ${binary}, expected ${expected}, got ${checksum}`,\n );\n }\n }\n // add the *final* path to the list of binaries\n paths.push(join(dir, relative(tempDir, path)));\n }\n\n // this directory shouldn't exist, but if two simultaneous `yarn foundryup`\n // processes are running, it might. Last process wins, so we remove other\n // `dir`s just in case.\n await rm(dir, rmOpts);\n // everything has been extracted; move the files to their final destination\n await rename(tempDir, dir);\n // return the list of extracted binaries\n return paths;\n } catch (error) {\n // if things fail for any reason try to clean up a bit. it is very important\n // to not leave `dir` behind, as its existence is a signal that the binaries\n // are installed.\n const rmErrors = (\n await Promise.allSettled([rm(tempDir, rmOpts), rm(dir, rmOpts)])\n )\n .filter((r) => r.status === 'rejected')\n .map((r) => (r as PromiseRejectedResult).reason);\n\n // if we failed to clean up, create an aggregate error message\n if (rmErrors.length) {\n throw new AggregateError(\n [error, ...rmErrors],\n 'This is a bug; you should report it.',\n );\n }\n throw error;\n }\n}\n/**\n * Extracts the binaries from a tar archive.\n *\n * @param url - The URL of the archive to extract the binaries from\n * @param binaries - The list of binaries to extract\n * @param dir - The destination directory\n * @param checksumAlgorithm - The checksum algorithm to use\n * @returns The list of binaries extracted\n */\n\n/**\n * Extracts the binaries from a tar archive.\n *\n * @param url - The URL of the archive to extract the binaries from\n * @param binaries - The list of binaries to extract\n * @param dir - The destination directory\n * @param checksumAlgorithm - The checksum algorithm to use\n * @returns The list of binaries extracted\n */\nasync function extractFromTar(\n url: URL,\n binaries: Binary[],\n dir: string,\n checksumAlgorithm?: string,\n) {\n const downloads: {\n path: string;\n binary: Binary;\n checksum?: string;\n }[] = [];\n await pipeline(\n startDownload(url),\n extractTar(\n {\n cwd: dir,\n transform: (entry) => {\n const absolutePath = entry.absolute;\n if (!absolutePath) {\n throw new Error('Missing absolute path for entry');\n }\n\n if (checksumAlgorithm) {\n const hash = createHash(checksumAlgorithm);\n const passThrough = new Minipass({ async: true });\n passThrough.pipe(hash);\n passThrough.on('end', () => {\n downloads.push({\n path: absolutePath,\n binary: entry.path as Binary,\n checksum: hash.digest('hex'),\n });\n });\n return passThrough;\n }\n\n // When no checksum is needed, record the entry and return undefined\n // to use the original stream without transformation\n downloads.push({\n path: absolutePath,\n binary: entry.path as Binary,\n });\n return undefined;\n },\n },\n binaries,\n ),\n );\n return downloads;\n}\n/**\n * Extracts the binaries from a zip archive.\n *\n * @param url - The URL of the archive to extract the binaries from\n * @param binaries - The list of binaries to extract\n * @param dir - The destination directory\n * @param checksumAlgorithm - The checksum algorithm to use\n * @returns The list of binaries extracted\n */\nasync function extractFromZip(\n url: URL,\n binaries: Binary[],\n dir: string,\n checksumAlgorithm?: string,\n) {\n const agent = new (url.protocol === 'http:' ? HttpAgent : HttpsAgent)({\n keepAlive: true,\n });\n const source: Source = {\n async size() {\n const download = startDownload(url, { agent, method: 'HEAD' });\n const response = await download.response();\n const contentLength = response.headers['content-length'];\n return contentLength ? parseInt(contentLength, 10) : 0;\n },\n stream(offset: number, bytes: number) {\n const options = {\n agent,\n headers: {\n range: `bytes=${offset}-${bytes ? offset + bytes : ''}`,\n },\n };\n return startDownload(url, options);\n },\n };\n\n const { files } = await Open.custom(source, {});\n const filtered = files.filter(({ path }) =>\n binaries.includes(basename(path, extname(path)) as Binary),\n );\n return await Promise.all(\n filtered.map(async ({ path, stream }) => {\n const dest = join(dir, path);\n const entry = stream();\n const destStream = createWriteStream(dest);\n const binary = basename(path, extname(path)) as Binary;\n if (checksumAlgorithm) {\n const hash = createHash(checksumAlgorithm);\n const hashStream = async function* (entryStream: Entry) {\n for await (const chunk of entryStream) {\n hash.update(chunk);\n yield chunk;\n }\n };\n await pipeline(entry, hashStream, destStream);\n return {\n path: dest,\n binary,\n checksum: hash.digest('hex'),\n };\n }\n await pipeline(entry, destStream);\n return {\n path: dest,\n binary,\n };\n }),\n );\n}\n"]}
1
+ {"version":3,"file":"extract.cjs","sourceRoot":"","sources":["../src/extract.ts"],"names":[],"mappings":"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","sourcesContent":["import { Minipass } from 'minipass';\nimport { ok } from 'node:assert/strict';\nimport { createHash } from 'node:crypto';\nimport { createWriteStream } from 'node:fs';\nimport { rename, mkdir, rm } from 'node:fs/promises';\nimport { Agent as HttpAgent } from 'node:http';\nimport { Agent as HttpsAgent } from 'node:https';\nimport { join, basename, extname, relative } from 'node:path';\nimport { pipeline } from 'node:stream/promises';\nimport { extract as extractTar } from 'tar';\nimport { Open } from 'unzipper';\nimport type { Source, Entry } from 'unzipper';\n\nimport { startDownload } from './download.js';\nimport { Extension } from './types.js';\nimport type { Binary } from './types.js';\nimport { say } from './utils.js';\n\n/**\n * Extracts the binaries from the given URL and writes them to the destination.\n *\n * @param url - The URL of the archive to extract the binaries from\n * @param binaries - The list of binaries to extract\n * @param dir - The destination directory\n * @param checksums - The checksums to verify the binaries against\n * @returns The list of binaries extracted\n */\n\n/**\n * Extracts the binaries from the given URL and writes them to the destination.\n *\n * @param url - The URL of the archive to extract the binaries from\n * @param binaries - The list of binaries to extract\n * @param dir - The destination directory\n * @param checksums - The checksums to verify the binaries against\n * @returns The list of binaries extracted\n */\nexport async function extractFrom(\n url: URL,\n binaries: Binary[],\n dir: string,\n checksums: { algorithm: string; binaries: Record<Binary, string> } | null,\n) {\n const extract = url.pathname.toLowerCase().endsWith(Extension.Tar)\n ? extractFromTar\n : extractFromZip;\n // write all files to a temporary directory first, then rename to the final\n // destination to avoid accidental partial extraction. We don't use\n // `os.tmpdir` for this because `rename` will fail if the directories are on\n // different file systems.\n const tempDir = `${dir}.downloading`;\n const rmOpts = { recursive: true, maxRetries: 3, force: true };\n try {\n // clean up any previous in-progress downloads\n await rm(tempDir, rmOpts);\n // make the temporary directory to extract the binaries to\n await mkdir(tempDir, { recursive: true });\n const downloads = await extract(\n url,\n binaries,\n tempDir,\n checksums?.algorithm,\n );\n ok(downloads.length === binaries.length, 'Failed to extract all binaries');\n\n const paths: string[] = [];\n for (const { path, binary, checksum } of downloads) {\n if (checksums) {\n say(`verifying checksum for ${binary}`);\n const expected = checksums.binaries[binary];\n if (checksum === expected) {\n say(`checksum verified for ${binary}`);\n } else {\n throw new Error(\n `checksum mismatch for ${binary}, expected ${expected}, got ${checksum}`,\n );\n }\n }\n // add the *final* path to the list of binaries\n paths.push(join(dir, relative(tempDir, path)));\n }\n\n // this directory shouldn't exist, but if two simultaneous `yarn foundryup`\n // processes are running, it might. Last process wins, so we remove other\n // `dir`s just in case.\n await rm(dir, rmOpts);\n // everything has been extracted; move the files to their final destination\n await rename(tempDir, dir);\n // return the list of extracted binaries\n return paths;\n } catch (error) {\n // if things fail for any reason try to clean up a bit. it is very important\n // to not leave `dir` behind, as its existence is a signal that the binaries\n // are installed.\n const rmErrors = (\n await Promise.allSettled([rm(tempDir, rmOpts), rm(dir, rmOpts)])\n )\n .filter((r) => r.status === 'rejected')\n .map((r) => (r as PromiseRejectedResult).reason);\n\n // if we failed to clean up, create an aggregate error message\n if (rmErrors.length) {\n throw new AggregateError(\n [error, ...rmErrors],\n 'This is a bug; you should report it.',\n );\n }\n throw error;\n }\n}\n/**\n * Extracts the binaries from a tar archive.\n *\n * @param url - The URL of the archive to extract the binaries from\n * @param binaries - The list of binaries to extract\n * @param dir - The destination directory\n * @param checksumAlgorithm - The checksum algorithm to use\n * @returns The list of binaries extracted\n */\n\n/**\n * Extracts the binaries from a tar archive.\n *\n * @param url - The URL of the archive to extract the binaries from\n * @param binaries - The list of binaries to extract\n * @param dir - The destination directory\n * @param checksumAlgorithm - The checksum algorithm to use\n * @returns The list of binaries extracted\n */\nasync function extractFromTar(\n url: URL,\n binaries: Binary[],\n dir: string,\n checksumAlgorithm?: string,\n) {\n const downloads: {\n path: string;\n binary: Binary;\n checksum?: string;\n }[] = [];\n await pipeline(\n startDownload(url),\n extractTar(\n {\n cwd: dir,\n // @ts-expect-error: Types here broke in `tar@7.5.12`, but it appears to\n // work fine as-is.\n // See: https://github.com/isaacs/node-tar/issues/459\n transform: (entry) => {\n const absolutePath = entry.absolute;\n if (!absolutePath) {\n throw new Error('Missing absolute path for entry');\n }\n\n if (checksumAlgorithm) {\n const hash = createHash(checksumAlgorithm);\n const passThrough = new Minipass({ async: true });\n passThrough.pipe(hash);\n passThrough.on('end', () => {\n downloads.push({\n path: absolutePath,\n binary: entry.path as Binary,\n checksum: hash.digest('hex'),\n });\n });\n return passThrough;\n }\n\n // When no checksum is needed, record the entry and return undefined\n // to use the original stream without transformation\n downloads.push({\n path: absolutePath,\n binary: entry.path as Binary,\n });\n return undefined;\n },\n },\n binaries,\n ),\n );\n return downloads;\n}\n/**\n * Extracts the binaries from a zip archive.\n *\n * @param url - The URL of the archive to extract the binaries from\n * @param binaries - The list of binaries to extract\n * @param dir - The destination directory\n * @param checksumAlgorithm - The checksum algorithm to use\n * @returns The list of binaries extracted\n */\nasync function extractFromZip(\n url: URL,\n binaries: Binary[],\n dir: string,\n checksumAlgorithm?: string,\n) {\n const agent = new (url.protocol === 'http:' ? HttpAgent : HttpsAgent)({\n keepAlive: true,\n });\n const source: Source = {\n async size() {\n const download = startDownload(url, { agent, method: 'HEAD' });\n const response = await download.response();\n const contentLength = response.headers['content-length'];\n return contentLength ? parseInt(contentLength, 10) : 0;\n },\n stream(offset: number, bytes: number) {\n const options = {\n agent,\n headers: {\n range: `bytes=${offset}-${bytes ? offset + bytes : ''}`,\n },\n };\n return startDownload(url, options);\n },\n };\n\n const { files } = await Open.custom(source, {});\n const filtered = files.filter(({ path }) =>\n binaries.includes(basename(path, extname(path)) as Binary),\n );\n return await Promise.all(\n filtered.map(async ({ path, stream }) => {\n const dest = join(dir, path);\n const entry = stream();\n const destStream = createWriteStream(dest);\n const binary = basename(path, extname(path)) as Binary;\n if (checksumAlgorithm) {\n const hash = createHash(checksumAlgorithm);\n const hashStream = async function* (entryStream: Entry) {\n for await (const chunk of entryStream) {\n hash.update(chunk);\n yield chunk;\n }\n };\n await pipeline(entry, hashStream, destStream);\n return {\n path: dest,\n binary,\n checksum: hash.digest('hex'),\n };\n }\n await pipeline(entry, destStream);\n return {\n path: dest,\n binary,\n };\n }),\n );\n}\n"]}
package/dist/extract.mjs CHANGED
@@ -107,6 +107,9 @@ async function extractFromTar(url, binaries, dir, checksumAlgorithm) {
107
107
  const downloads = [];
108
108
  await pipeline(startDownload(url), extractTar({
109
109
  cwd: dir,
110
+ // @ts-expect-error: Types here broke in `tar@7.5.12`, but it appears to
111
+ // work fine as-is.
112
+ // See: https://github.com/isaacs/node-tar/issues/459
110
113
  transform: (entry) => {
111
114
  const absolutePath = entry.absolute;
112
115
  if (!absolutePath) {
@@ -1 +1 @@
1
- {"version":3,"file":"extract.mjs","sourceRoot":"","sources":["../src/extract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,iBAAiB;AACpC,OAAO,EAAE,EAAE,EAAE,2BAA2B;AACxC,OAAO,EAAE,UAAU,EAAE,oBAAoB;AACzC,OAAO,EAAE,iBAAiB,EAAE,gBAAgB;AAC5C,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,yBAAyB;AACrD,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,kBAAkB;AAC/C,OAAO,EAAE,KAAK,IAAI,UAAU,EAAE,mBAAmB;AACjD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,kBAAkB;AAC9D,OAAO,EAAE,QAAQ,EAAE,6BAA6B;AAChD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,YAAY;AAC5C,OAAO,EAAE,IAAI,EAAE,iBAAiB;AAGhC,OAAO,EAAE,aAAa,EAAE,uBAAsB;AAC9C,OAAO,EAAE,SAAS,EAAE,oBAAmB;AAEvC,OAAO,EAAE,GAAG,EAAE,oBAAmB;AAEjC;;;;;;;;GAQG;AAEH;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,GAAQ,EACR,QAAkB,EAClB,GAAW,EACX,SAAyE;IAEzE,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC;QAChE,CAAC,CAAC,cAAc;QAChB,CAAC,CAAC,cAAc,CAAC;IACnB,2EAA2E;IAC3E,mEAAmE;IACnE,4EAA4E;IAC5E,0BAA0B;IAC1B,MAAM,OAAO,GAAG,GAAG,GAAG,cAAc,CAAC;IACrC,MAAM,MAAM,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAC/D,IAAI,CAAC;QACH,8CAA8C;QAC9C,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1B,0DAA0D;QAC1D,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,MAAM,SAAS,GAAG,MAAM,OAAO,CAC7B,GAAG,EACH,QAAQ,EACR,OAAO,EACP,SAAS,EAAE,SAAS,CACrB,CAAC;QACF,EAAE,CAAC,SAAS,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,EAAE,gCAAgC,CAAC,CAAC;QAE3E,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,SAAS,EAAE,CAAC;YACnD,IAAI,SAAS,EAAE,CAAC;gBACd,GAAG,CAAC,0BAA0B,MAAM,EAAE,CAAC,CAAC;gBACxC,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;gBAC5C,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;oBAC1B,GAAG,CAAC,yBAAyB,MAAM,EAAE,CAAC,CAAC;gBACzC,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,KAAK,CACb,yBAAyB,MAAM,cAAc,QAAQ,SAAS,QAAQ,EAAE,CACzE,CAAC;gBACJ,CAAC;YACH,CAAC;YACD,+CAA+C;YAC/C,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QACjD,CAAC;QAED,2EAA2E;QAC3E,yEAAyE;QACzE,uBAAuB;QACvB,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;QACtB,2EAA2E;QAC3E,MAAM,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC3B,wCAAwC;QACxC,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,4EAA4E;QAC5E,4EAA4E;QAC5E,iBAAiB;QACjB,MAAM,QAAQ,GAAG,CACf,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CACjE;aACE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,UAAU,CAAC;aACtC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAE,CAA2B,CAAC,MAAM,CAAC,CAAC;QAEnD,8DAA8D;QAC9D,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,IAAI,cAAc,CACtB,CAAC,KAAK,EAAE,GAAG,QAAQ,CAAC,EACpB,sCAAsC,CACvC,CAAC;QACJ,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AACD;;;;;;;;GAQG;AAEH;;;;;;;;GAQG;AACH,KAAK,UAAU,cAAc,CAC3B,GAAQ,EACR,QAAkB,EAClB,GAAW,EACX,iBAA0B;IAE1B,MAAM,SAAS,GAIT,EAAE,CAAC;IACT,MAAM,QAAQ,CACZ,aAAa,CAAC,GAAG,CAAC,EAClB,UAAU,CACR;QACE,GAAG,EAAE,GAAG;QACR,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;YACnB,MAAM,YAAY,GAAG,KAAK,CAAC,QAAQ,CAAC;YACpC,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;YACrD,CAAC;YAED,IAAI,iBAAiB,EAAE,CAAC;gBACtB,MAAM,IAAI,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC;gBAC3C,MAAM,WAAW,GAAG,IAAI,QAAQ,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBAClD,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACvB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;oBACzB,SAAS,CAAC,IAAI,CAAC;wBACb,IAAI,EAAE,YAAY;wBAClB,MAAM,EAAE,KAAK,CAAC,IAAc;wBAC5B,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;qBAC7B,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;gBACH,OAAO,WAAW,CAAC;YACrB,CAAC;YAED,oEAAoE;YACpE,oDAAoD;YACpD,SAAS,CAAC,IAAI,CAAC;gBACb,IAAI,EAAE,YAAY;gBAClB,MAAM,EAAE,KAAK,CAAC,IAAc;aAC7B,CAAC,CAAC;YACH,OAAO,SAAS,CAAC;QACnB,CAAC;KACF,EACD,QAAQ,CACT,CACF,CAAC;IACF,OAAO,SAAS,CAAC;AACnB,CAAC;AACD;;;;;;;;GAQG;AACH,KAAK,UAAU,cAAc,CAC3B,GAAQ,EACR,QAAkB,EAClB,GAAW,EACX,iBAA0B;IAE1B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QACpE,SAAS,EAAE,IAAI;KAChB,CAAC,CAAC;IACH,MAAM,MAAM,GAAW;QACrB,KAAK,CAAC,IAAI;YACR,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;YAC/D,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC;YAC3C,MAAM,aAAa,GAAG,QAAQ,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;YACzD,OAAO,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzD,CAAC;QACD,MAAM,CAAC,MAAc,EAAE,KAAa;YAClC,MAAM,OAAO,GAAG;gBACd,KAAK;gBACL,OAAO,EAAE;oBACP,KAAK,EAAE,SAAS,MAAM,IAAI,KAAK,CAAC,CAAC,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;iBACxD;aACF,CAAC;YACF,OAAO,aAAa,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QACrC,CAAC;KACF,CAAC;IAEF,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CACzC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAW,CAAC,CAC3D,CAAC;IACF,OAAO,MAAM,OAAO,CAAC,GAAG,CACtB,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC;QACvB,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAW,CAAC;QACvD,IAAI,iBAAiB,EAAE,CAAC;YACtB,MAAM,IAAI,GAAG,UAAU,CAAC,iBAAiB,CAAC,CAAC;YAC3C,MAAM,UAAU,GAAG,KAAK,SAAS,CAAC,EAAE,WAAkB;gBACpD,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,WAAW,EAAE,CAAC;oBACtC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBACnB,MAAM,KAAK,CAAC;gBACd,CAAC;YACH,CAAC,CAAC;YACF,MAAM,QAAQ,CAAC,KAAK,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;YAC9C,OAAO;gBACL,IAAI,EAAE,IAAI;gBACV,MAAM;gBACN,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;aAC7B,CAAC;QACJ,CAAC;QACD,MAAM,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAClC,OAAO;YACL,IAAI,EAAE,IAAI;YACV,MAAM;SACP,CAAC;IACJ,CAAC,CAAC,CACH,CAAC;AACJ,CAAC","sourcesContent":["import { Minipass } from 'minipass';\nimport { ok } from 'node:assert/strict';\nimport { createHash } from 'node:crypto';\nimport { createWriteStream } from 'node:fs';\nimport { rename, mkdir, rm } from 'node:fs/promises';\nimport { Agent as HttpAgent } from 'node:http';\nimport { Agent as HttpsAgent } from 'node:https';\nimport { join, basename, extname, relative } from 'node:path';\nimport { pipeline } from 'node:stream/promises';\nimport { extract as extractTar } from 'tar';\nimport { Open } from 'unzipper';\nimport type { Source, Entry } from 'unzipper';\n\nimport { startDownload } from './download.js';\nimport { Extension } from './types.js';\nimport type { Binary } from './types.js';\nimport { say } from './utils.js';\n\n/**\n * Extracts the binaries from the given URL and writes them to the destination.\n *\n * @param url - The URL of the archive to extract the binaries from\n * @param binaries - The list of binaries to extract\n * @param dir - The destination directory\n * @param checksums - The checksums to verify the binaries against\n * @returns The list of binaries extracted\n */\n\n/**\n * Extracts the binaries from the given URL and writes them to the destination.\n *\n * @param url - The URL of the archive to extract the binaries from\n * @param binaries - The list of binaries to extract\n * @param dir - The destination directory\n * @param checksums - The checksums to verify the binaries against\n * @returns The list of binaries extracted\n */\nexport async function extractFrom(\n url: URL,\n binaries: Binary[],\n dir: string,\n checksums: { algorithm: string; binaries: Record<Binary, string> } | null,\n) {\n const extract = url.pathname.toLowerCase().endsWith(Extension.Tar)\n ? extractFromTar\n : extractFromZip;\n // write all files to a temporary directory first, then rename to the final\n // destination to avoid accidental partial extraction. We don't use\n // `os.tmpdir` for this because `rename` will fail if the directories are on\n // different file systems.\n const tempDir = `${dir}.downloading`;\n const rmOpts = { recursive: true, maxRetries: 3, force: true };\n try {\n // clean up any previous in-progress downloads\n await rm(tempDir, rmOpts);\n // make the temporary directory to extract the binaries to\n await mkdir(tempDir, { recursive: true });\n const downloads = await extract(\n url,\n binaries,\n tempDir,\n checksums?.algorithm,\n );\n ok(downloads.length === binaries.length, 'Failed to extract all binaries');\n\n const paths: string[] = [];\n for (const { path, binary, checksum } of downloads) {\n if (checksums) {\n say(`verifying checksum for ${binary}`);\n const expected = checksums.binaries[binary];\n if (checksum === expected) {\n say(`checksum verified for ${binary}`);\n } else {\n throw new Error(\n `checksum mismatch for ${binary}, expected ${expected}, got ${checksum}`,\n );\n }\n }\n // add the *final* path to the list of binaries\n paths.push(join(dir, relative(tempDir, path)));\n }\n\n // this directory shouldn't exist, but if two simultaneous `yarn foundryup`\n // processes are running, it might. Last process wins, so we remove other\n // `dir`s just in case.\n await rm(dir, rmOpts);\n // everything has been extracted; move the files to their final destination\n await rename(tempDir, dir);\n // return the list of extracted binaries\n return paths;\n } catch (error) {\n // if things fail for any reason try to clean up a bit. it is very important\n // to not leave `dir` behind, as its existence is a signal that the binaries\n // are installed.\n const rmErrors = (\n await Promise.allSettled([rm(tempDir, rmOpts), rm(dir, rmOpts)])\n )\n .filter((r) => r.status === 'rejected')\n .map((r) => (r as PromiseRejectedResult).reason);\n\n // if we failed to clean up, create an aggregate error message\n if (rmErrors.length) {\n throw new AggregateError(\n [error, ...rmErrors],\n 'This is a bug; you should report it.',\n );\n }\n throw error;\n }\n}\n/**\n * Extracts the binaries from a tar archive.\n *\n * @param url - The URL of the archive to extract the binaries from\n * @param binaries - The list of binaries to extract\n * @param dir - The destination directory\n * @param checksumAlgorithm - The checksum algorithm to use\n * @returns The list of binaries extracted\n */\n\n/**\n * Extracts the binaries from a tar archive.\n *\n * @param url - The URL of the archive to extract the binaries from\n * @param binaries - The list of binaries to extract\n * @param dir - The destination directory\n * @param checksumAlgorithm - The checksum algorithm to use\n * @returns The list of binaries extracted\n */\nasync function extractFromTar(\n url: URL,\n binaries: Binary[],\n dir: string,\n checksumAlgorithm?: string,\n) {\n const downloads: {\n path: string;\n binary: Binary;\n checksum?: string;\n }[] = [];\n await pipeline(\n startDownload(url),\n extractTar(\n {\n cwd: dir,\n transform: (entry) => {\n const absolutePath = entry.absolute;\n if (!absolutePath) {\n throw new Error('Missing absolute path for entry');\n }\n\n if (checksumAlgorithm) {\n const hash = createHash(checksumAlgorithm);\n const passThrough = new Minipass({ async: true });\n passThrough.pipe(hash);\n passThrough.on('end', () => {\n downloads.push({\n path: absolutePath,\n binary: entry.path as Binary,\n checksum: hash.digest('hex'),\n });\n });\n return passThrough;\n }\n\n // When no checksum is needed, record the entry and return undefined\n // to use the original stream without transformation\n downloads.push({\n path: absolutePath,\n binary: entry.path as Binary,\n });\n return undefined;\n },\n },\n binaries,\n ),\n );\n return downloads;\n}\n/**\n * Extracts the binaries from a zip archive.\n *\n * @param url - The URL of the archive to extract the binaries from\n * @param binaries - The list of binaries to extract\n * @param dir - The destination directory\n * @param checksumAlgorithm - The checksum algorithm to use\n * @returns The list of binaries extracted\n */\nasync function extractFromZip(\n url: URL,\n binaries: Binary[],\n dir: string,\n checksumAlgorithm?: string,\n) {\n const agent = new (url.protocol === 'http:' ? HttpAgent : HttpsAgent)({\n keepAlive: true,\n });\n const source: Source = {\n async size() {\n const download = startDownload(url, { agent, method: 'HEAD' });\n const response = await download.response();\n const contentLength = response.headers['content-length'];\n return contentLength ? parseInt(contentLength, 10) : 0;\n },\n stream(offset: number, bytes: number) {\n const options = {\n agent,\n headers: {\n range: `bytes=${offset}-${bytes ? offset + bytes : ''}`,\n },\n };\n return startDownload(url, options);\n },\n };\n\n const { files } = await Open.custom(source, {});\n const filtered = files.filter(({ path }) =>\n binaries.includes(basename(path, extname(path)) as Binary),\n );\n return await Promise.all(\n filtered.map(async ({ path, stream }) => {\n const dest = join(dir, path);\n const entry = stream();\n const destStream = createWriteStream(dest);\n const binary = basename(path, extname(path)) as Binary;\n if (checksumAlgorithm) {\n const hash = createHash(checksumAlgorithm);\n const hashStream = async function* (entryStream: Entry) {\n for await (const chunk of entryStream) {\n hash.update(chunk);\n yield chunk;\n }\n };\n await pipeline(entry, hashStream, destStream);\n return {\n path: dest,\n binary,\n checksum: hash.digest('hex'),\n };\n }\n await pipeline(entry, destStream);\n return {\n path: dest,\n binary,\n };\n }),\n );\n}\n"]}
1
+ {"version":3,"file":"extract.mjs","sourceRoot":"","sources":["../src/extract.ts"],"names":[],"mappings":"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","sourcesContent":["import { Minipass } from 'minipass';\nimport { ok } from 'node:assert/strict';\nimport { createHash } from 'node:crypto';\nimport { createWriteStream } from 'node:fs';\nimport { rename, mkdir, rm } from 'node:fs/promises';\nimport { Agent as HttpAgent } from 'node:http';\nimport { Agent as HttpsAgent } from 'node:https';\nimport { join, basename, extname, relative } from 'node:path';\nimport { pipeline } from 'node:stream/promises';\nimport { extract as extractTar } from 'tar';\nimport { Open } from 'unzipper';\nimport type { Source, Entry } from 'unzipper';\n\nimport { startDownload } from './download.js';\nimport { Extension } from './types.js';\nimport type { Binary } from './types.js';\nimport { say } from './utils.js';\n\n/**\n * Extracts the binaries from the given URL and writes them to the destination.\n *\n * @param url - The URL of the archive to extract the binaries from\n * @param binaries - The list of binaries to extract\n * @param dir - The destination directory\n * @param checksums - The checksums to verify the binaries against\n * @returns The list of binaries extracted\n */\n\n/**\n * Extracts the binaries from the given URL and writes them to the destination.\n *\n * @param url - The URL of the archive to extract the binaries from\n * @param binaries - The list of binaries to extract\n * @param dir - The destination directory\n * @param checksums - The checksums to verify the binaries against\n * @returns The list of binaries extracted\n */\nexport async function extractFrom(\n url: URL,\n binaries: Binary[],\n dir: string,\n checksums: { algorithm: string; binaries: Record<Binary, string> } | null,\n) {\n const extract = url.pathname.toLowerCase().endsWith(Extension.Tar)\n ? extractFromTar\n : extractFromZip;\n // write all files to a temporary directory first, then rename to the final\n // destination to avoid accidental partial extraction. We don't use\n // `os.tmpdir` for this because `rename` will fail if the directories are on\n // different file systems.\n const tempDir = `${dir}.downloading`;\n const rmOpts = { recursive: true, maxRetries: 3, force: true };\n try {\n // clean up any previous in-progress downloads\n await rm(tempDir, rmOpts);\n // make the temporary directory to extract the binaries to\n await mkdir(tempDir, { recursive: true });\n const downloads = await extract(\n url,\n binaries,\n tempDir,\n checksums?.algorithm,\n );\n ok(downloads.length === binaries.length, 'Failed to extract all binaries');\n\n const paths: string[] = [];\n for (const { path, binary, checksum } of downloads) {\n if (checksums) {\n say(`verifying checksum for ${binary}`);\n const expected = checksums.binaries[binary];\n if (checksum === expected) {\n say(`checksum verified for ${binary}`);\n } else {\n throw new Error(\n `checksum mismatch for ${binary}, expected ${expected}, got ${checksum}`,\n );\n }\n }\n // add the *final* path to the list of binaries\n paths.push(join(dir, relative(tempDir, path)));\n }\n\n // this directory shouldn't exist, but if two simultaneous `yarn foundryup`\n // processes are running, it might. Last process wins, so we remove other\n // `dir`s just in case.\n await rm(dir, rmOpts);\n // everything has been extracted; move the files to their final destination\n await rename(tempDir, dir);\n // return the list of extracted binaries\n return paths;\n } catch (error) {\n // if things fail for any reason try to clean up a bit. it is very important\n // to not leave `dir` behind, as its existence is a signal that the binaries\n // are installed.\n const rmErrors = (\n await Promise.allSettled([rm(tempDir, rmOpts), rm(dir, rmOpts)])\n )\n .filter((r) => r.status === 'rejected')\n .map((r) => (r as PromiseRejectedResult).reason);\n\n // if we failed to clean up, create an aggregate error message\n if (rmErrors.length) {\n throw new AggregateError(\n [error, ...rmErrors],\n 'This is a bug; you should report it.',\n );\n }\n throw error;\n }\n}\n/**\n * Extracts the binaries from a tar archive.\n *\n * @param url - The URL of the archive to extract the binaries from\n * @param binaries - The list of binaries to extract\n * @param dir - The destination directory\n * @param checksumAlgorithm - The checksum algorithm to use\n * @returns The list of binaries extracted\n */\n\n/**\n * Extracts the binaries from a tar archive.\n *\n * @param url - The URL of the archive to extract the binaries from\n * @param binaries - The list of binaries to extract\n * @param dir - The destination directory\n * @param checksumAlgorithm - The checksum algorithm to use\n * @returns The list of binaries extracted\n */\nasync function extractFromTar(\n url: URL,\n binaries: Binary[],\n dir: string,\n checksumAlgorithm?: string,\n) {\n const downloads: {\n path: string;\n binary: Binary;\n checksum?: string;\n }[] = [];\n await pipeline(\n startDownload(url),\n extractTar(\n {\n cwd: dir,\n // @ts-expect-error: Types here broke in `tar@7.5.12`, but it appears to\n // work fine as-is.\n // See: https://github.com/isaacs/node-tar/issues/459\n transform: (entry) => {\n const absolutePath = entry.absolute;\n if (!absolutePath) {\n throw new Error('Missing absolute path for entry');\n }\n\n if (checksumAlgorithm) {\n const hash = createHash(checksumAlgorithm);\n const passThrough = new Minipass({ async: true });\n passThrough.pipe(hash);\n passThrough.on('end', () => {\n downloads.push({\n path: absolutePath,\n binary: entry.path as Binary,\n checksum: hash.digest('hex'),\n });\n });\n return passThrough;\n }\n\n // When no checksum is needed, record the entry and return undefined\n // to use the original stream without transformation\n downloads.push({\n path: absolutePath,\n binary: entry.path as Binary,\n });\n return undefined;\n },\n },\n binaries,\n ),\n );\n return downloads;\n}\n/**\n * Extracts the binaries from a zip archive.\n *\n * @param url - The URL of the archive to extract the binaries from\n * @param binaries - The list of binaries to extract\n * @param dir - The destination directory\n * @param checksumAlgorithm - The checksum algorithm to use\n * @returns The list of binaries extracted\n */\nasync function extractFromZip(\n url: URL,\n binaries: Binary[],\n dir: string,\n checksumAlgorithm?: string,\n) {\n const agent = new (url.protocol === 'http:' ? HttpAgent : HttpsAgent)({\n keepAlive: true,\n });\n const source: Source = {\n async size() {\n const download = startDownload(url, { agent, method: 'HEAD' });\n const response = await download.response();\n const contentLength = response.headers['content-length'];\n return contentLength ? parseInt(contentLength, 10) : 0;\n },\n stream(offset: number, bytes: number) {\n const options = {\n agent,\n headers: {\n range: `bytes=${offset}-${bytes ? offset + bytes : ''}`,\n },\n };\n return startDownload(url, options);\n },\n };\n\n const { files } = await Open.custom(source, {});\n const filtered = files.filter(({ path }) =>\n binaries.includes(basename(path, extname(path)) as Binary),\n );\n return await Promise.all(\n filtered.map(async ({ path, stream }) => {\n const dest = join(dir, path);\n const entry = stream();\n const destStream = createWriteStream(dest);\n const binary = basename(path, extname(path)) as Binary;\n if (checksumAlgorithm) {\n const hash = createHash(checksumAlgorithm);\n const hashStream = async function* (entryStream: Entry) {\n for await (const chunk of entryStream) {\n hash.update(chunk);\n yield chunk;\n }\n };\n await pipeline(entry, hashStream, destStream);\n return {\n path: dest,\n binary,\n checksum: hash.digest('hex'),\n };\n }\n await pipeline(entry, destStream);\n return {\n path: dest,\n binary,\n };\n }),\n );\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metamask-previews/foundryup",
3
- "version": "1.0.1-preview-5ae42f53d",
3
+ "version": "1.0.1-preview-e2b065b23",
4
4
  "description": "foundryup",
5
5
  "keywords": [
6
6
  "Ethereum",