@metamask-previews/foundryup 0.0.0-preview-c1fef6e5 → 1.0.0-preview-d2bf8ff

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.
Files changed (53) hide show
  1. package/CHANGELOG.md +17 -1
  2. package/README.md +0 -4
  3. package/dist/cli.cjs +16 -3
  4. package/dist/cli.cjs.map +1 -1
  5. package/dist/cli.mjs +16 -3
  6. package/dist/cli.mjs.map +1 -1
  7. package/dist/download.cjs +11 -3
  8. package/dist/download.cjs.map +1 -1
  9. package/dist/download.d.cts +8 -0
  10. package/dist/download.d.cts.map +1 -1
  11. package/dist/download.d.mts +8 -0
  12. package/dist/download.d.mts.map +1 -1
  13. package/dist/download.mjs +11 -3
  14. package/dist/download.mjs.map +1 -1
  15. package/dist/extract.cjs +20 -2
  16. package/dist/extract.cjs.map +1 -1
  17. package/dist/extract.d.cts +10 -1
  18. package/dist/extract.d.cts.map +1 -1
  19. package/dist/extract.d.mts +10 -1
  20. package/dist/extract.d.mts.map +1 -1
  21. package/dist/extract.mjs +21 -3
  22. package/dist/extract.mjs.map +1 -1
  23. package/dist/index.cjs +48 -5
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.cts +46 -3
  26. package/dist/index.d.cts.map +1 -1
  27. package/dist/index.d.mts +46 -3
  28. package/dist/index.d.mts.map +1 -1
  29. package/dist/index.mjs +51 -9
  30. package/dist/index.mjs.map +1 -1
  31. package/dist/options.cjs +24 -2
  32. package/dist/options.cjs.map +1 -1
  33. package/dist/options.d.cts +9 -0
  34. package/dist/options.d.cts.map +1 -1
  35. package/dist/options.d.mts +9 -0
  36. package/dist/options.d.mts.map +1 -1
  37. package/dist/options.mjs +24 -2
  38. package/dist/options.mjs.map +1 -1
  39. package/dist/types.cjs.map +1 -1
  40. package/dist/types.d.cts +4 -2
  41. package/dist/types.d.cts.map +1 -1
  42. package/dist/types.d.mts +4 -2
  43. package/dist/types.d.mts.map +1 -1
  44. package/dist/types.mjs.map +1 -1
  45. package/dist/utils.cjs +9 -3
  46. package/dist/utils.cjs.map +1 -1
  47. package/dist/utils.d.cts +10 -4
  48. package/dist/utils.d.cts.map +1 -1
  49. package/dist/utils.d.mts +10 -4
  50. package/dist/utils.d.mts.map +1 -1
  51. package/dist/utils.mjs +10 -4
  52. package/dist/utils.mjs.map +1 -1
  53. package/package.json +15 -9
package/dist/index.cjs CHANGED
@@ -2,17 +2,24 @@
2
2
  "use strict";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.downloadAndInstallFoundryBinaries = exports.installBinaries = exports.checkAndDownloadBinaries = exports.getBinaryArchiveUrl = exports.getCacheDirectory = void 0;
5
- const node_path_1 = require("node:path");
6
- const node_os_1 = require("node:os");
5
+ const node_crypto_1 = require("node:crypto");
7
6
  const node_fs_1 = require("node:fs");
8
7
  const promises_1 = require("node:fs/promises");
9
- const node_crypto_1 = require("node:crypto");
8
+ const node_os_1 = require("node:os");
9
+ const node_path_1 = require("node:path");
10
10
  const node_process_1 = require("node:process");
11
11
  const yaml_1 = require("yaml");
12
- const utils_1 = require("./utils.cjs");
13
12
  const extract_1 = require("./extract.cjs");
14
13
  const options_1 = require("./options.cjs");
15
14
  const types_1 = require("./types.cjs");
15
+ const utils_1 = require("./utils.cjs");
16
+ /**
17
+ * Determines the cache directory based on the .yarnrc.yml configuration.
18
+ * If global cache is enabled, returns a path in the user's home directory.
19
+ * Otherwise, returns a local cache path in the current working directory.
20
+ *
21
+ * @returns The path to the cache directory
22
+ */
16
23
  function getCacheDirectory() {
17
24
  let enableGlobalCache = false;
18
25
  try {
@@ -33,11 +40,32 @@ function getCacheDirectory() {
33
40
  : (0, node_path_1.join)((0, node_process_1.cwd)(), '.metamask', 'cache');
34
41
  }
35
42
  exports.getCacheDirectory = getCacheDirectory;
43
+ /**
44
+ * Generates the URL for downloading the Foundry binary archive.
45
+ *
46
+ * @param repo - The GitHub repository (e.g., 'foundry-rs/foundry')
47
+ * @param tag - The release tag (e.g., 'v1.0.0')
48
+ * @param version - The version string
49
+ * @param platform - The target platform (e.g., Platform.Linux)
50
+ * @param arch - The target architecture (e.g., 'amd64')
51
+ * @returns The URL for the binary archive
52
+ */
36
53
  function getBinaryArchiveUrl(repo, tag, version, platform, arch) {
37
54
  const ext = platform === types_1.Platform.Windows ? types_1.Extension.Zip : types_1.Extension.Tar;
38
55
  return `https://github.com/${repo}/releases/download/${tag}/foundry_${version}_${platform}_${arch}.${ext}`;
39
56
  }
40
57
  exports.getBinaryArchiveUrl = getBinaryArchiveUrl;
58
+ /**
59
+ * Checks if binaries are already in the cache. If not, downloads and extracts them.
60
+ *
61
+ * @param url - The URL to download the binaries from
62
+ * @param binaries - The list of binaries to download
63
+ * @param cachePath - The path to the cache directory
64
+ * @param platform - The target platform
65
+ * @param arch - The target architecture
66
+ * @param checksums - Optional checksums for verification
67
+ * @returns A promise that resolves to the directory containing the downloaded binaries
68
+ */
41
69
  async function checkAndDownloadBinaries(url, binaries, cachePath, platform, arch, checksums) {
42
70
  let downloadedBinaries;
43
71
  try {
@@ -61,6 +89,14 @@ async function checkAndDownloadBinaries(url, binaries, cachePath, platform, arch
61
89
  return downloadedBinaries;
62
90
  }
63
91
  exports.checkAndDownloadBinaries = checkAndDownloadBinaries;
92
+ /**
93
+ * Installs the downloaded binaries by creating symlinks or copying files.
94
+ *
95
+ * @param downloadedBinaries - The directory containing the downloaded binaries
96
+ * @param BIN_DIR - The target directory for installation
97
+ * @param cachePath - The path to the cache directory
98
+ * @returns A promise that resolves when installation is complete
99
+ */
64
100
  async function installBinaries(downloadedBinaries, BIN_DIR, cachePath) {
65
101
  for await (const file of downloadedBinaries) {
66
102
  if (!file.isFile()) {
@@ -85,10 +121,17 @@ async function installBinaries(downloadedBinaries, BIN_DIR, cachePath) {
85
121
  await (0, promises_1.copyFile)(target, path);
86
122
  }
87
123
  // check that it works by logging the version
88
- (0, utils_1.say)(`installed - ${(0, utils_1.getVersion)(path)}`);
124
+ (0, utils_1.say)(`installed - ${(0, utils_1.getVersion)(path).toString()}`);
89
125
  }
90
126
  }
91
127
  exports.installBinaries = installBinaries;
128
+ /**
129
+ * Downloads and installs Foundry binaries based on command-line arguments.
130
+ * If the command is 'cache clean', it removes the cache directory.
131
+ * Otherwise, it downloads and installs the specified binaries.
132
+ *
133
+ * @returns A promise that resolves when the operation is complete
134
+ */
92
135
  async function downloadAndInstallFoundryBinaries() {
93
136
  const parsedArgs = (0, options_1.parseArgs)();
94
137
  const CACHE_DIR = getCacheDirectory();
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env -S node --require \"./node_modules/tsx/dist/preflight.cjs\" --import \"./node_modules/tsx/dist/loader.mjs\"\n\nimport { join, relative } from 'node:path';\nimport { homedir } from 'node:os';\nimport { Dir, readFileSync } from 'node:fs';\nimport { copyFile, mkdir, opendir, rm, symlink, unlink } from 'node:fs/promises';\nimport { createHash } from 'node:crypto';\nimport { cwd, exit } from 'node:process';\nimport { parse as parseYaml } from 'yaml';\nimport {\n getVersion,\n isCodedError,\n noop,\n say,\n transformChecksums,\n} from './utils';\nimport { extractFrom } from './extract';\nimport { parseArgs, printBanner } from './options';\nimport type { Checksums } from './types';\nimport { Architecture, Binary, Extension, Platform } from './types';\n\nexport function getCacheDirectory(): string {\n let enableGlobalCache = false;\n try {\n const configFileContent = readFileSync('.yarnrc.yml', 'utf8');\n const parsedConfig = parseYaml(configFileContent);\n enableGlobalCache = parsedConfig?.enableGlobalCache ?? false;\n } catch (error) {\n // If file doesn't exist or can't be read, default to local cache\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return join(cwd(), '.metamask', 'cache');\n }\n // For other errors, log but continue with default\n console.warn('Warning: Error reading .yarnrc.yml, using local cache:', error);\n }\n return enableGlobalCache\n ? join(homedir(), '.cache', 'metamask')\n : join(cwd(), '.metamask', 'cache');\n}\n\nexport function getBinaryArchiveUrl(\n repo: string,\n tag: string,\n version: string,\n platform: Platform,\n arch: string,\n): string {\n const ext = platform === Platform.Windows ? Extension.Zip : Extension.Tar;\n return `https://github.com/${repo}/releases/download/${tag}/foundry_${version}_${platform}_${arch}.${ext}`;\n}\n\nexport async function checkAndDownloadBinaries(\n url: URL,\n binaries: Binary[],\n cachePath: string,\n platform: Platform,\n arch: Architecture,\n checksums?: Checksums,\n): Promise<Dir> {\n let downloadedBinaries: Dir;\n try {\n say(`checking cache`);\n downloadedBinaries = await opendir(cachePath);\n say(`found binaries in cache`);\n } catch (e: unknown) {\n say(`binaries not in cache`);\n if ((e as NodeJS.ErrnoException).code === 'ENOENT') {\n say(`installing from ${url.toString()}`);\n // directory doesn't exist, download and extract\n const platformChecksums = transformChecksums(checksums, platform, arch);\n await extractFrom(url, binaries, cachePath, platformChecksums);\n downloadedBinaries = await opendir(cachePath);\n } else {\n throw e;\n }\n }\n return downloadedBinaries;\n}\n\nexport async function installBinaries(\n downloadedBinaries: Dir,\n BIN_DIR: string,\n cachePath: string,\n): Promise<void> {\n for await (const file of downloadedBinaries) {\n if (!file.isFile()) {\n continue;\n }\n const target = join(file.parentPath, file.name);\n const path = join(BIN_DIR, relative(cachePath, target));\n\n // create the BIN_DIR paths if they don't exists already\n await mkdir(BIN_DIR, { recursive: true });\n\n // clean up any existing files or symlinks\n await unlink(path).catch(noop);\n try {\n // create new symlink\n await symlink(target, path);\n } catch (e) {\n if (!(isCodedError(e) && ['EPERM', 'EXDEV'].includes(e.code))) {\n throw e;\n }\n // symlinking can fail if it's a cross-device/filesystem link, or for\n // permissions reasons, so we'll just copy the file instead\n await copyFile(target, path);\n }\n // check that it works by logging the version\n say(`installed - ${getVersion(path)}`);\n }\n}\n\nexport async function downloadAndInstallFoundryBinaries(): Promise<void> {\n const parsedArgs = parseArgs();\n\n const CACHE_DIR = getCacheDirectory();\n\n if (parsedArgs.command === 'cache clean') {\n await rm(CACHE_DIR, { recursive: true, force: true });\n say('done!');\n exit(0);\n }\n\n const {\n repo,\n version: { version, tag },\n arch,\n platform,\n binaries,\n checksums,\n } = parsedArgs.options;\n\n printBanner();\n const bins = binaries.join(', ');\n say(`fetching ${bins} ${version} for ${platform} ${arch}`);\n\n const BIN_ARCHIVE_URL = getBinaryArchiveUrl(\n repo,\n tag,\n version,\n platform,\n arch,\n );\n const BIN_DIR = join(cwd(), 'node_modules', '.bin');\n\n const url = new URL(BIN_ARCHIVE_URL);\n const cacheKey = createHash('sha256')\n .update(`${BIN_ARCHIVE_URL}-${bins}`)\n .digest('hex');\n const cachePath = join(CACHE_DIR, cacheKey);\n\n const downloadedBinaries = await checkAndDownloadBinaries(\n url,\n binaries,\n cachePath,\n platform,\n arch,\n checksums,\n );\n\n await installBinaries(downloadedBinaries, BIN_DIR, cachePath);\n\n say('done!');\n}\n"]}
1
+ {"version":3,"file":"index.cjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env -S node --require \"./node_modules/tsx/dist/preflight.cjs\" --import \"./node_modules/tsx/dist/loader.mjs\"\n\nimport { createHash } from 'node:crypto';\nimport { readFileSync } from 'node:fs';\nimport type { Dir } from 'node:fs';\nimport {\n copyFile,\n mkdir,\n opendir,\n rm,\n symlink,\n unlink,\n} from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join, relative } from 'node:path';\nimport { cwd, exit } from 'node:process';\nimport { parse as parseYaml } from 'yaml';\n\nimport { extractFrom } from './extract';\nimport { parseArgs, printBanner } from './options';\nimport type { Checksums, Architecture, Binary } from './types';\nimport { Extension, Platform } from './types';\nimport {\n getVersion,\n isCodedError,\n noop,\n say,\n transformChecksums,\n} from './utils';\n\n/**\n * Determines the cache directory based on the .yarnrc.yml configuration.\n * If global cache is enabled, returns a path in the user's home directory.\n * Otherwise, returns a local cache path in the current working directory.\n *\n * @returns The path to the cache directory\n */\nexport function getCacheDirectory(): string {\n let enableGlobalCache = false;\n try {\n const configFileContent = readFileSync('.yarnrc.yml', 'utf8');\n const parsedConfig = parseYaml(configFileContent);\n enableGlobalCache = parsedConfig?.enableGlobalCache ?? false;\n } catch (error) {\n // If file doesn't exist or can't be read, default to local cache\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return join(cwd(), '.metamask', 'cache');\n }\n // For other errors, log but continue with default\n console.warn(\n 'Warning: Error reading .yarnrc.yml, using local cache:',\n error,\n );\n }\n return enableGlobalCache\n ? join(homedir(), '.cache', 'metamask')\n : join(cwd(), '.metamask', 'cache');\n}\n\n/**\n * Generates the URL for downloading the Foundry binary archive.\n *\n * @param repo - The GitHub repository (e.g., 'foundry-rs/foundry')\n * @param tag - The release tag (e.g., 'v1.0.0')\n * @param version - The version string\n * @param platform - The target platform (e.g., Platform.Linux)\n * @param arch - The target architecture (e.g., 'amd64')\n * @returns The URL for the binary archive\n */\nexport function getBinaryArchiveUrl(\n repo: string,\n tag: string,\n version: string,\n platform: Platform,\n arch: string,\n): string {\n const ext = platform === Platform.Windows ? Extension.Zip : Extension.Tar;\n return `https://github.com/${repo}/releases/download/${tag}/foundry_${version}_${platform}_${arch}.${ext}`;\n}\n\n/**\n * Checks if binaries are already in the cache. If not, downloads and extracts them.\n *\n * @param url - The URL to download the binaries from\n * @param binaries - The list of binaries to download\n * @param cachePath - The path to the cache directory\n * @param platform - The target platform\n * @param arch - The target architecture\n * @param checksums - Optional checksums for verification\n * @returns A promise that resolves to the directory containing the downloaded binaries\n */\nexport async function checkAndDownloadBinaries(\n url: URL,\n binaries: Binary[],\n cachePath: string,\n platform: Platform,\n arch: Architecture,\n checksums?: Checksums,\n): Promise<Dir> {\n let downloadedBinaries: Dir;\n try {\n say(`checking cache`);\n downloadedBinaries = await opendir(cachePath);\n say(`found binaries in cache`);\n } catch (e: unknown) {\n say(`binaries not in cache`);\n if ((e as NodeJS.ErrnoException).code === 'ENOENT') {\n say(`installing from ${url.toString()}`);\n // directory doesn't exist, download and extract\n const platformChecksums = transformChecksums(checksums, platform, arch);\n await extractFrom(url, binaries, cachePath, platformChecksums);\n downloadedBinaries = await opendir(cachePath);\n } else {\n throw e;\n }\n }\n return downloadedBinaries;\n}\n\n/**\n * Installs the downloaded binaries by creating symlinks or copying files.\n *\n * @param downloadedBinaries - The directory containing the downloaded binaries\n * @param BIN_DIR - The target directory for installation\n * @param cachePath - The path to the cache directory\n * @returns A promise that resolves when installation is complete\n */\nexport async function installBinaries(\n downloadedBinaries: Dir,\n BIN_DIR: string,\n cachePath: string,\n): Promise<void> {\n for await (const file of downloadedBinaries) {\n if (!file.isFile()) {\n continue;\n }\n const target = join(file.parentPath, file.name);\n const path = join(BIN_DIR, relative(cachePath, target));\n\n // create the BIN_DIR paths if they don't exists already\n await mkdir(BIN_DIR, { recursive: true });\n\n // clean up any existing files or symlinks\n await unlink(path).catch(noop);\n try {\n // create new symlink\n await symlink(target, path);\n } catch (e) {\n if (!(isCodedError(e) && ['EPERM', 'EXDEV'].includes(e.code))) {\n throw e;\n }\n // symlinking can fail if it's a cross-device/filesystem link, or for\n // permissions reasons, so we'll just copy the file instead\n await copyFile(target, path);\n }\n // check that it works by logging the version\n say(`installed - ${getVersion(path).toString()}`);\n }\n}\n\n/**\n * Downloads and installs Foundry binaries based on command-line arguments.\n * If the command is 'cache clean', it removes the cache directory.\n * Otherwise, it downloads and installs the specified binaries.\n *\n * @returns A promise that resolves when the operation is complete\n */\nexport async function downloadAndInstallFoundryBinaries(): Promise<void> {\n const parsedArgs = parseArgs();\n\n const CACHE_DIR = getCacheDirectory();\n\n if (parsedArgs.command === 'cache clean') {\n await rm(CACHE_DIR, { recursive: true, force: true });\n say('done!');\n exit(0);\n }\n\n const {\n repo,\n version: { version, tag },\n arch,\n platform,\n binaries,\n checksums,\n } = parsedArgs.options;\n\n printBanner();\n const bins = binaries.join(', ');\n say(`fetching ${bins} ${version} for ${platform} ${arch}`);\n\n const BIN_ARCHIVE_URL = getBinaryArchiveUrl(\n repo,\n tag,\n version,\n platform,\n arch,\n );\n const BIN_DIR = join(cwd(), 'node_modules', '.bin');\n\n const url = new URL(BIN_ARCHIVE_URL);\n const cacheKey = createHash('sha256')\n .update(`${BIN_ARCHIVE_URL}-${bins}`)\n .digest('hex');\n const cachePath = join(CACHE_DIR, cacheKey);\n\n const downloadedBinaries = await checkAndDownloadBinaries(\n url,\n binaries,\n cachePath,\n platform,\n arch,\n checksums,\n );\n\n await installBinaries(downloadedBinaries, BIN_DIR, cachePath);\n\n say('done!');\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -1,11 +1,54 @@
1
1
  #!/usr/bin/env -S node --require "./node_modules/tsx/dist/preflight.cjs" --import "./node_modules/tsx/dist/loader.mjs"
2
2
  /// <reference types="node" />
3
- import { Dir } from "node:fs";
4
- import type { Checksums } from "./types.cjs";
5
- import { Architecture, Binary, Platform } from "./types.cjs";
3
+ import type { Dir } from "node:fs";
4
+ import type { Checksums, Architecture, Binary } from "./types.cjs";
5
+ import { Platform } from "./types.cjs";
6
+ /**
7
+ * Determines the cache directory based on the .yarnrc.yml configuration.
8
+ * If global cache is enabled, returns a path in the user's home directory.
9
+ * Otherwise, returns a local cache path in the current working directory.
10
+ *
11
+ * @returns The path to the cache directory
12
+ */
6
13
  export declare function getCacheDirectory(): string;
14
+ /**
15
+ * Generates the URL for downloading the Foundry binary archive.
16
+ *
17
+ * @param repo - The GitHub repository (e.g., 'foundry-rs/foundry')
18
+ * @param tag - The release tag (e.g., 'v1.0.0')
19
+ * @param version - The version string
20
+ * @param platform - The target platform (e.g., Platform.Linux)
21
+ * @param arch - The target architecture (e.g., 'amd64')
22
+ * @returns The URL for the binary archive
23
+ */
7
24
  export declare function getBinaryArchiveUrl(repo: string, tag: string, version: string, platform: Platform, arch: string): string;
25
+ /**
26
+ * Checks if binaries are already in the cache. If not, downloads and extracts them.
27
+ *
28
+ * @param url - The URL to download the binaries from
29
+ * @param binaries - The list of binaries to download
30
+ * @param cachePath - The path to the cache directory
31
+ * @param platform - The target platform
32
+ * @param arch - The target architecture
33
+ * @param checksums - Optional checksums for verification
34
+ * @returns A promise that resolves to the directory containing the downloaded binaries
35
+ */
8
36
  export declare function checkAndDownloadBinaries(url: URL, binaries: Binary[], cachePath: string, platform: Platform, arch: Architecture, checksums?: Checksums): Promise<Dir>;
37
+ /**
38
+ * Installs the downloaded binaries by creating symlinks or copying files.
39
+ *
40
+ * @param downloadedBinaries - The directory containing the downloaded binaries
41
+ * @param BIN_DIR - The target directory for installation
42
+ * @param cachePath - The path to the cache directory
43
+ * @returns A promise that resolves when installation is complete
44
+ */
9
45
  export declare function installBinaries(downloadedBinaries: Dir, BIN_DIR: string, cachePath: string): Promise<void>;
46
+ /**
47
+ * Downloads and installs Foundry binaries based on command-line arguments.
48
+ * If the command is 'cache clean', it removes the cache directory.
49
+ * Otherwise, it downloads and installs the specified binaries.
50
+ *
51
+ * @returns A promise that resolves when the operation is complete
52
+ */
10
53
  export declare function downloadAndInstallFoundryBinaries(): Promise<void>;
11
54
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAIA,OAAO,EAAE,GAAG,EAAgB,gBAAgB;AAc5C,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAgB;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAa,QAAQ,EAAE,oBAAgB;AAEpE,wBAAgB,iBAAiB,IAAI,MAAM,CAiB1C;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,GACX,MAAM,CAGR;AAED,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,MAAM,EAAE,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,YAAY,EAClB,SAAS,CAAC,EAAE,SAAS,GACpB,OAAO,CAAC,GAAG,CAAC,CAmBd;AAED,wBAAsB,eAAe,CACnC,kBAAkB,EAAE,GAAG,EACvB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CA2Bf;AAED,wBAAsB,iCAAiC,IAAI,OAAO,CAAC,IAAI,CAAC,CAmDvE"}
1
+ {"version":3,"file":"index.d.cts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAIA,OAAO,KAAK,EAAE,GAAG,EAAE,gBAAgB;AAgBnC,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,oBAAgB;AAC/D,OAAO,EAAa,QAAQ,EAAE,oBAAgB;AAS9C;;;;;;GAMG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAoB1C;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,GACX,MAAM,CAGR;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,MAAM,EAAE,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,YAAY,EAClB,SAAS,CAAC,EAAE,SAAS,GACpB,OAAO,CAAC,GAAG,CAAC,CAmBd;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,kBAAkB,EAAE,GAAG,EACvB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CA2Bf;AAED;;;;;;GAMG;AACH,wBAAsB,iCAAiC,IAAI,OAAO,CAAC,IAAI,CAAC,CAmDvE"}
package/dist/index.d.mts CHANGED
@@ -1,11 +1,54 @@
1
1
  #!/usr/bin/env -S node --require "./node_modules/tsx/dist/preflight.cjs" --import "./node_modules/tsx/dist/loader.mjs"
2
2
  /// <reference types="node" />
3
- import { Dir } from "node:fs";
4
- import type { Checksums } from "./types.mjs";
5
- import { Architecture, Binary, Platform } from "./types.mjs";
3
+ import type { Dir } from "node:fs";
4
+ import type { Checksums, Architecture, Binary } from "./types.mjs";
5
+ import { Platform } from "./types.mjs";
6
+ /**
7
+ * Determines the cache directory based on the .yarnrc.yml configuration.
8
+ * If global cache is enabled, returns a path in the user's home directory.
9
+ * Otherwise, returns a local cache path in the current working directory.
10
+ *
11
+ * @returns The path to the cache directory
12
+ */
6
13
  export declare function getCacheDirectory(): string;
14
+ /**
15
+ * Generates the URL for downloading the Foundry binary archive.
16
+ *
17
+ * @param repo - The GitHub repository (e.g., 'foundry-rs/foundry')
18
+ * @param tag - The release tag (e.g., 'v1.0.0')
19
+ * @param version - The version string
20
+ * @param platform - The target platform (e.g., Platform.Linux)
21
+ * @param arch - The target architecture (e.g., 'amd64')
22
+ * @returns The URL for the binary archive
23
+ */
7
24
  export declare function getBinaryArchiveUrl(repo: string, tag: string, version: string, platform: Platform, arch: string): string;
25
+ /**
26
+ * Checks if binaries are already in the cache. If not, downloads and extracts them.
27
+ *
28
+ * @param url - The URL to download the binaries from
29
+ * @param binaries - The list of binaries to download
30
+ * @param cachePath - The path to the cache directory
31
+ * @param platform - The target platform
32
+ * @param arch - The target architecture
33
+ * @param checksums - Optional checksums for verification
34
+ * @returns A promise that resolves to the directory containing the downloaded binaries
35
+ */
8
36
  export declare function checkAndDownloadBinaries(url: URL, binaries: Binary[], cachePath: string, platform: Platform, arch: Architecture, checksums?: Checksums): Promise<Dir>;
37
+ /**
38
+ * Installs the downloaded binaries by creating symlinks or copying files.
39
+ *
40
+ * @param downloadedBinaries - The directory containing the downloaded binaries
41
+ * @param BIN_DIR - The target directory for installation
42
+ * @param cachePath - The path to the cache directory
43
+ * @returns A promise that resolves when installation is complete
44
+ */
9
45
  export declare function installBinaries(downloadedBinaries: Dir, BIN_DIR: string, cachePath: string): Promise<void>;
46
+ /**
47
+ * Downloads and installs Foundry binaries based on command-line arguments.
48
+ * If the command is 'cache clean', it removes the cache directory.
49
+ * Otherwise, it downloads and installs the specified binaries.
50
+ *
51
+ * @returns A promise that resolves when the operation is complete
52
+ */
10
53
  export declare function downloadAndInstallFoundryBinaries(): Promise<void>;
11
54
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAIA,OAAO,EAAE,GAAG,EAAgB,gBAAgB;AAc5C,OAAO,KAAK,EAAE,SAAS,EAAE,oBAAgB;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,EAAa,QAAQ,EAAE,oBAAgB;AAEpE,wBAAgB,iBAAiB,IAAI,MAAM,CAiB1C;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,GACX,MAAM,CAGR;AAED,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,MAAM,EAAE,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,YAAY,EAClB,SAAS,CAAC,EAAE,SAAS,GACpB,OAAO,CAAC,GAAG,CAAC,CAmBd;AAED,wBAAsB,eAAe,CACnC,kBAAkB,EAAE,GAAG,EACvB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CA2Bf;AAED,wBAAsB,iCAAiC,IAAI,OAAO,CAAC,IAAI,CAAC,CAmDvE"}
1
+ {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAIA,OAAO,KAAK,EAAE,GAAG,EAAE,gBAAgB;AAgBnC,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,oBAAgB;AAC/D,OAAO,EAAa,QAAQ,EAAE,oBAAgB;AAS9C;;;;;;GAMG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAoB1C;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,GACX,MAAM,CAGR;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,MAAM,EAAE,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,YAAY,EAClB,SAAS,CAAC,EAAE,SAAS,GACpB,OAAO,CAAC,GAAG,CAAC,CAmBd;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,kBAAkB,EAAE,GAAG,EACvB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CA2Bf;AAED;;;;;;GAMG;AACH,wBAAsB,iCAAiC,IAAI,OAAO,CAAC,IAAI,CAAC,CAmDvE"}
package/dist/index.mjs CHANGED
@@ -1,16 +1,22 @@
1
1
  #!/usr/bin/env -S node --require "./node_modules/tsx/dist/preflight.cjs" --import "./node_modules/tsx/dist/loader.mjs"
2
- import { join, relative } from "node:path";
3
- import { homedir } from "node:os";
4
- import { Dir, readFileSync } from "node:fs";
5
- import { copyFile, mkdir, opendir, rm, symlink, unlink } from "node:fs/promises";
6
2
  import { createHash } from "node:crypto";
3
+ import { readFileSync } from "node:fs";
4
+ import { copyFile, mkdir, opendir, rm, symlink, unlink } from "node:fs/promises";
5
+ import { homedir } from "node:os";
6
+ import { join, relative } from "node:path";
7
7
  import { cwd, exit } from "node:process";
8
- import $yaml from "yaml";
9
- const { parse: parseYaml } = $yaml;
10
- import { getVersion, isCodedError, noop, say, transformChecksums } from "./utils.mjs";
8
+ import { parse as parseYaml } from "yaml";
11
9
  import { extractFrom } from "./extract.mjs";
12
10
  import { parseArgs, printBanner } from "./options.mjs";
13
- import { Architecture, Binary, Extension, Platform } from "./types.mjs";
11
+ import { Extension, Platform } from "./types.mjs";
12
+ import { getVersion, isCodedError, noop, say, transformChecksums } from "./utils.mjs";
13
+ /**
14
+ * Determines the cache directory based on the .yarnrc.yml configuration.
15
+ * If global cache is enabled, returns a path in the user's home directory.
16
+ * Otherwise, returns a local cache path in the current working directory.
17
+ *
18
+ * @returns The path to the cache directory
19
+ */
14
20
  export function getCacheDirectory() {
15
21
  let enableGlobalCache = false;
16
22
  try {
@@ -30,10 +36,31 @@ export function getCacheDirectory() {
30
36
  ? join(homedir(), '.cache', 'metamask')
31
37
  : join(cwd(), '.metamask', 'cache');
32
38
  }
39
+ /**
40
+ * Generates the URL for downloading the Foundry binary archive.
41
+ *
42
+ * @param repo - The GitHub repository (e.g., 'foundry-rs/foundry')
43
+ * @param tag - The release tag (e.g., 'v1.0.0')
44
+ * @param version - The version string
45
+ * @param platform - The target platform (e.g., Platform.Linux)
46
+ * @param arch - The target architecture (e.g., 'amd64')
47
+ * @returns The URL for the binary archive
48
+ */
33
49
  export function getBinaryArchiveUrl(repo, tag, version, platform, arch) {
34
50
  const ext = platform === Platform.Windows ? Extension.Zip : Extension.Tar;
35
51
  return `https://github.com/${repo}/releases/download/${tag}/foundry_${version}_${platform}_${arch}.${ext}`;
36
52
  }
53
+ /**
54
+ * Checks if binaries are already in the cache. If not, downloads and extracts them.
55
+ *
56
+ * @param url - The URL to download the binaries from
57
+ * @param binaries - The list of binaries to download
58
+ * @param cachePath - The path to the cache directory
59
+ * @param platform - The target platform
60
+ * @param arch - The target architecture
61
+ * @param checksums - Optional checksums for verification
62
+ * @returns A promise that resolves to the directory containing the downloaded binaries
63
+ */
37
64
  export async function checkAndDownloadBinaries(url, binaries, cachePath, platform, arch, checksums) {
38
65
  let downloadedBinaries;
39
66
  try {
@@ -56,6 +83,14 @@ export async function checkAndDownloadBinaries(url, binaries, cachePath, platfor
56
83
  }
57
84
  return downloadedBinaries;
58
85
  }
86
+ /**
87
+ * Installs the downloaded binaries by creating symlinks or copying files.
88
+ *
89
+ * @param downloadedBinaries - The directory containing the downloaded binaries
90
+ * @param BIN_DIR - The target directory for installation
91
+ * @param cachePath - The path to the cache directory
92
+ * @returns A promise that resolves when installation is complete
93
+ */
59
94
  export async function installBinaries(downloadedBinaries, BIN_DIR, cachePath) {
60
95
  for await (const file of downloadedBinaries) {
61
96
  if (!file.isFile()) {
@@ -80,9 +115,16 @@ export async function installBinaries(downloadedBinaries, BIN_DIR, cachePath) {
80
115
  await copyFile(target, path);
81
116
  }
82
117
  // check that it works by logging the version
83
- say(`installed - ${getVersion(path)}`);
118
+ say(`installed - ${getVersion(path).toString()}`);
84
119
  }
85
120
  }
121
+ /**
122
+ * Downloads and installs Foundry binaries based on command-line arguments.
123
+ * If the command is 'cache clean', it removes the cache directory.
124
+ * Otherwise, it downloads and installs the specified binaries.
125
+ *
126
+ * @returns A promise that resolves when the operation is complete
127
+ */
86
128
  export async function downloadAndInstallFoundryBinaries() {
87
129
  const parsedArgs = parseArgs();
88
130
  const CACHE_DIR = getCacheDirectory();
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env -S node --require \"./node_modules/tsx/dist/preflight.cjs\" --import \"./node_modules/tsx/dist/loader.mjs\"\n\nimport { join, relative } from 'node:path';\nimport { homedir } from 'node:os';\nimport { Dir, readFileSync } from 'node:fs';\nimport { copyFile, mkdir, opendir, rm, symlink, unlink } from 'node:fs/promises';\nimport { createHash } from 'node:crypto';\nimport { cwd, exit } from 'node:process';\nimport { parse as parseYaml } from 'yaml';\nimport {\n getVersion,\n isCodedError,\n noop,\n say,\n transformChecksums,\n} from './utils';\nimport { extractFrom } from './extract';\nimport { parseArgs, printBanner } from './options';\nimport type { Checksums } from './types';\nimport { Architecture, Binary, Extension, Platform } from './types';\n\nexport function getCacheDirectory(): string {\n let enableGlobalCache = false;\n try {\n const configFileContent = readFileSync('.yarnrc.yml', 'utf8');\n const parsedConfig = parseYaml(configFileContent);\n enableGlobalCache = parsedConfig?.enableGlobalCache ?? false;\n } catch (error) {\n // If file doesn't exist or can't be read, default to local cache\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return join(cwd(), '.metamask', 'cache');\n }\n // For other errors, log but continue with default\n console.warn('Warning: Error reading .yarnrc.yml, using local cache:', error);\n }\n return enableGlobalCache\n ? join(homedir(), '.cache', 'metamask')\n : join(cwd(), '.metamask', 'cache');\n}\n\nexport function getBinaryArchiveUrl(\n repo: string,\n tag: string,\n version: string,\n platform: Platform,\n arch: string,\n): string {\n const ext = platform === Platform.Windows ? Extension.Zip : Extension.Tar;\n return `https://github.com/${repo}/releases/download/${tag}/foundry_${version}_${platform}_${arch}.${ext}`;\n}\n\nexport async function checkAndDownloadBinaries(\n url: URL,\n binaries: Binary[],\n cachePath: string,\n platform: Platform,\n arch: Architecture,\n checksums?: Checksums,\n): Promise<Dir> {\n let downloadedBinaries: Dir;\n try {\n say(`checking cache`);\n downloadedBinaries = await opendir(cachePath);\n say(`found binaries in cache`);\n } catch (e: unknown) {\n say(`binaries not in cache`);\n if ((e as NodeJS.ErrnoException).code === 'ENOENT') {\n say(`installing from ${url.toString()}`);\n // directory doesn't exist, download and extract\n const platformChecksums = transformChecksums(checksums, platform, arch);\n await extractFrom(url, binaries, cachePath, platformChecksums);\n downloadedBinaries = await opendir(cachePath);\n } else {\n throw e;\n }\n }\n return downloadedBinaries;\n}\n\nexport async function installBinaries(\n downloadedBinaries: Dir,\n BIN_DIR: string,\n cachePath: string,\n): Promise<void> {\n for await (const file of downloadedBinaries) {\n if (!file.isFile()) {\n continue;\n }\n const target = join(file.parentPath, file.name);\n const path = join(BIN_DIR, relative(cachePath, target));\n\n // create the BIN_DIR paths if they don't exists already\n await mkdir(BIN_DIR, { recursive: true });\n\n // clean up any existing files or symlinks\n await unlink(path).catch(noop);\n try {\n // create new symlink\n await symlink(target, path);\n } catch (e) {\n if (!(isCodedError(e) && ['EPERM', 'EXDEV'].includes(e.code))) {\n throw e;\n }\n // symlinking can fail if it's a cross-device/filesystem link, or for\n // permissions reasons, so we'll just copy the file instead\n await copyFile(target, path);\n }\n // check that it works by logging the version\n say(`installed - ${getVersion(path)}`);\n }\n}\n\nexport async function downloadAndInstallFoundryBinaries(): Promise<void> {\n const parsedArgs = parseArgs();\n\n const CACHE_DIR = getCacheDirectory();\n\n if (parsedArgs.command === 'cache clean') {\n await rm(CACHE_DIR, { recursive: true, force: true });\n say('done!');\n exit(0);\n }\n\n const {\n repo,\n version: { version, tag },\n arch,\n platform,\n binaries,\n checksums,\n } = parsedArgs.options;\n\n printBanner();\n const bins = binaries.join(', ');\n say(`fetching ${bins} ${version} for ${platform} ${arch}`);\n\n const BIN_ARCHIVE_URL = getBinaryArchiveUrl(\n repo,\n tag,\n version,\n platform,\n arch,\n );\n const BIN_DIR = join(cwd(), 'node_modules', '.bin');\n\n const url = new URL(BIN_ARCHIVE_URL);\n const cacheKey = createHash('sha256')\n .update(`${BIN_ARCHIVE_URL}-${bins}`)\n .digest('hex');\n const cachePath = join(CACHE_DIR, cacheKey);\n\n const downloadedBinaries = await checkAndDownloadBinaries(\n url,\n binaries,\n cachePath,\n platform,\n arch,\n checksums,\n );\n\n await installBinaries(downloadedBinaries, BIN_DIR, cachePath);\n\n say('done!');\n}\n"]}
1
+ {"version":3,"file":"index.mjs","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env -S node --require \"./node_modules/tsx/dist/preflight.cjs\" --import \"./node_modules/tsx/dist/loader.mjs\"\n\nimport { createHash } from 'node:crypto';\nimport { readFileSync } from 'node:fs';\nimport type { Dir } from 'node:fs';\nimport {\n copyFile,\n mkdir,\n opendir,\n rm,\n symlink,\n unlink,\n} from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join, relative } from 'node:path';\nimport { cwd, exit } from 'node:process';\nimport { parse as parseYaml } from 'yaml';\n\nimport { extractFrom } from './extract';\nimport { parseArgs, printBanner } from './options';\nimport type { Checksums, Architecture, Binary } from './types';\nimport { Extension, Platform } from './types';\nimport {\n getVersion,\n isCodedError,\n noop,\n say,\n transformChecksums,\n} from './utils';\n\n/**\n * Determines the cache directory based on the .yarnrc.yml configuration.\n * If global cache is enabled, returns a path in the user's home directory.\n * Otherwise, returns a local cache path in the current working directory.\n *\n * @returns The path to the cache directory\n */\nexport function getCacheDirectory(): string {\n let enableGlobalCache = false;\n try {\n const configFileContent = readFileSync('.yarnrc.yml', 'utf8');\n const parsedConfig = parseYaml(configFileContent);\n enableGlobalCache = parsedConfig?.enableGlobalCache ?? false;\n } catch (error) {\n // If file doesn't exist or can't be read, default to local cache\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return join(cwd(), '.metamask', 'cache');\n }\n // For other errors, log but continue with default\n console.warn(\n 'Warning: Error reading .yarnrc.yml, using local cache:',\n error,\n );\n }\n return enableGlobalCache\n ? join(homedir(), '.cache', 'metamask')\n : join(cwd(), '.metamask', 'cache');\n}\n\n/**\n * Generates the URL for downloading the Foundry binary archive.\n *\n * @param repo - The GitHub repository (e.g., 'foundry-rs/foundry')\n * @param tag - The release tag (e.g., 'v1.0.0')\n * @param version - The version string\n * @param platform - The target platform (e.g., Platform.Linux)\n * @param arch - The target architecture (e.g., 'amd64')\n * @returns The URL for the binary archive\n */\nexport function getBinaryArchiveUrl(\n repo: string,\n tag: string,\n version: string,\n platform: Platform,\n arch: string,\n): string {\n const ext = platform === Platform.Windows ? Extension.Zip : Extension.Tar;\n return `https://github.com/${repo}/releases/download/${tag}/foundry_${version}_${platform}_${arch}.${ext}`;\n}\n\n/**\n * Checks if binaries are already in the cache. If not, downloads and extracts them.\n *\n * @param url - The URL to download the binaries from\n * @param binaries - The list of binaries to download\n * @param cachePath - The path to the cache directory\n * @param platform - The target platform\n * @param arch - The target architecture\n * @param checksums - Optional checksums for verification\n * @returns A promise that resolves to the directory containing the downloaded binaries\n */\nexport async function checkAndDownloadBinaries(\n url: URL,\n binaries: Binary[],\n cachePath: string,\n platform: Platform,\n arch: Architecture,\n checksums?: Checksums,\n): Promise<Dir> {\n let downloadedBinaries: Dir;\n try {\n say(`checking cache`);\n downloadedBinaries = await opendir(cachePath);\n say(`found binaries in cache`);\n } catch (e: unknown) {\n say(`binaries not in cache`);\n if ((e as NodeJS.ErrnoException).code === 'ENOENT') {\n say(`installing from ${url.toString()}`);\n // directory doesn't exist, download and extract\n const platformChecksums = transformChecksums(checksums, platform, arch);\n await extractFrom(url, binaries, cachePath, platformChecksums);\n downloadedBinaries = await opendir(cachePath);\n } else {\n throw e;\n }\n }\n return downloadedBinaries;\n}\n\n/**\n * Installs the downloaded binaries by creating symlinks or copying files.\n *\n * @param downloadedBinaries - The directory containing the downloaded binaries\n * @param BIN_DIR - The target directory for installation\n * @param cachePath - The path to the cache directory\n * @returns A promise that resolves when installation is complete\n */\nexport async function installBinaries(\n downloadedBinaries: Dir,\n BIN_DIR: string,\n cachePath: string,\n): Promise<void> {\n for await (const file of downloadedBinaries) {\n if (!file.isFile()) {\n continue;\n }\n const target = join(file.parentPath, file.name);\n const path = join(BIN_DIR, relative(cachePath, target));\n\n // create the BIN_DIR paths if they don't exists already\n await mkdir(BIN_DIR, { recursive: true });\n\n // clean up any existing files or symlinks\n await unlink(path).catch(noop);\n try {\n // create new symlink\n await symlink(target, path);\n } catch (e) {\n if (!(isCodedError(e) && ['EPERM', 'EXDEV'].includes(e.code))) {\n throw e;\n }\n // symlinking can fail if it's a cross-device/filesystem link, or for\n // permissions reasons, so we'll just copy the file instead\n await copyFile(target, path);\n }\n // check that it works by logging the version\n say(`installed - ${getVersion(path).toString()}`);\n }\n}\n\n/**\n * Downloads and installs Foundry binaries based on command-line arguments.\n * If the command is 'cache clean', it removes the cache directory.\n * Otherwise, it downloads and installs the specified binaries.\n *\n * @returns A promise that resolves when the operation is complete\n */\nexport async function downloadAndInstallFoundryBinaries(): Promise<void> {\n const parsedArgs = parseArgs();\n\n const CACHE_DIR = getCacheDirectory();\n\n if (parsedArgs.command === 'cache clean') {\n await rm(CACHE_DIR, { recursive: true, force: true });\n say('done!');\n exit(0);\n }\n\n const {\n repo,\n version: { version, tag },\n arch,\n platform,\n binaries,\n checksums,\n } = parsedArgs.options;\n\n printBanner();\n const bins = binaries.join(', ');\n say(`fetching ${bins} ${version} for ${platform} ${arch}`);\n\n const BIN_ARCHIVE_URL = getBinaryArchiveUrl(\n repo,\n tag,\n version,\n platform,\n arch,\n );\n const BIN_DIR = join(cwd(), 'node_modules', '.bin');\n\n const url = new URL(BIN_ARCHIVE_URL);\n const cacheKey = createHash('sha256')\n .update(`${BIN_ARCHIVE_URL}-${bins}`)\n .digest('hex');\n const cachePath = join(CACHE_DIR, cacheKey);\n\n const downloadedBinaries = await checkAndDownloadBinaries(\n url,\n binaries,\n cachePath,\n platform,\n arch,\n checksums,\n );\n\n await installBinaries(downloadedBinaries, BIN_DIR, cachePath);\n\n say('done!');\n}\n"]}
package/dist/options.cjs CHANGED
@@ -7,11 +7,20 @@ exports.parseArgs = exports.printBanner = void 0;
7
7
  const node_os_1 = require("node:os");
8
8
  const node_process_1 = require("node:process");
9
9
  const yargs_1 = __importDefault(require("yargs/yargs"));
10
- const utils_1 = require("./utils.cjs");
11
10
  const types_1 = require("./types.cjs");
11
+ const utils_1 = require("./utils.cjs");
12
+ /**
13
+ * Type guard to check if a string is a valid version string starting with 'v'.
14
+ *
15
+ * @param value - The string to check
16
+ * @returns True if the string is a valid version string
17
+ */
12
18
  function isVersionString(value) {
13
19
  return /^v\d/u.test(value);
14
20
  }
21
+ /**
22
+ * Prints the Foundry banner to the console.
23
+ */
15
24
  function printBanner() {
16
25
  console.log(`
17
26
  .xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx
@@ -32,6 +41,12 @@ Contribute : https://github.com/orgs/foundry-rs/projects/2/
32
41
  `);
33
42
  }
34
43
  exports.printBanner = printBanner;
44
+ /**
45
+ * Parses command line arguments and returns the parsed options.
46
+ *
47
+ * @param args - Command line arguments to parse
48
+ * @returns Parsed command line arguments
49
+ */
35
50
  function parseArgs(args = node_process_1.argv.slice(2)) {
36
51
  const { $0, _, ...parsed } = (0, yargs_1.default)()
37
52
  // Ensure unrecognized commands/options are reported as errors.
@@ -70,6 +85,13 @@ function parseArgs(args = node_process_1.argv.slice(2)) {
70
85
  }
71
86
  exports.parseArgs = parseArgs;
72
87
  const Binaries = Object.values(types_1.Binary);
88
+ /**
89
+ * Returns the command line options configuration.
90
+ *
91
+ * @param defaultPlatform - Default platform to use
92
+ * @param defaultArch - Default architecture to use
93
+ * @returns Command line options configuration
94
+ */
73
95
  function getOptions(defaultPlatform = (0, node_os_1.platform)(), defaultArch = (0, utils_1.normalizeSystemArchitecture)()) {
74
96
  return {
75
97
  binaries: {
@@ -106,7 +128,7 @@ function getOptions(defaultPlatform = (0, node_os_1.platform)(), defaultArch = (
106
128
  description: 'Specify the version (see: https://github.com/foundry-rs/foundry/tags)',
107
129
  default: 'nightly',
108
130
  coerce: (rawVersion) => {
109
- if (/^nightly/u.test(rawVersion)) {
131
+ if (rawVersion.startsWith('nightly')) {
110
132
  return { version: 'nightly', tag: rawVersion };
111
133
  // we don't validate the version much, we just trust the user
112
134
  }
@@ -1 +1 @@
1
- {"version":3,"file":"options.cjs","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":";;;;;;AAAA,qCAAmC;AACnC,+CAA4C;AAC5C,wDAAgC;AAChC,uCAAsD;AACtD,uCASiB;AAEjB,SAAS,eAAe,CAAC,KAAa;IACpC,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED,SAAgB,WAAW;IACzB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;CAgBb,CAAC,CAAC;AACH,CAAC;AAlBD,kCAkBC;AAED,SAAgB,SAAS,CAAC,OAAiB,mBAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IACtD,MAAM,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,MAAM,EAAE,GAAG,IAAA,eAAK,GAAE;QAClC,+DAA+D;SAC9D,MAAM,EAAE;QACT,yDAAyD;SACxD,OAAO,CAAC,KAAK,CAAC;QACf,wCAAwC;SACvC,UAAU,CAAC,gBAAgB,CAAC;QAC7B,iEAAiE;SAChE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,qBAAM,CAAC,OAAO,CAAC,CAAC;SACnC,mBAAmB,CAAC;QACnB,eAAe,EAAE,IAAI;QACrB,cAAc,EAAE,IAAI;KACrB,CAAC;QACF,yEAAyE;QACzE,uDAAuD;SACtD,GAAG,CAAC,WAAW,CAAC;SAChB,OAAO,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,0BAA0B,EAAE,CAAC,OAAO,EAAE,EAAE;QAClE,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACrD,CAAC,CAAC;SACD,OAAO,CAAC,OAAO,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,EAAE;QAChC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,+BAA+B,CAAC,CAAC,aAAa,EAAE,CAAC;IAC5E,CAAC,CAAC;SACD,SAAS,CAAC,IAAI,CAAC,CAAC;IAEnB,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5B,IAAI,OAAO,KAAK,aAAa,EAAE;QAC7B,OAAO;YACL,OAAO;SACC,CAAC;KACZ;IAED,uEAAuE;IACvE,OAAO;QACL,OAAO,EAAE,SAAS;QAClB,OAAO,EAAE,MAAsD;KACvD,CAAC;AACb,CAAC;AArCD,8BAqCC;AAED,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,cAAM,CAAkB,CAAC;AAExD,SAAS,UAAU,CACjB,eAAe,GAAG,IAAA,kBAAQ,GAAE,EAC5B,WAAW,GAAG,IAAA,mCAA2B,GAAE;IAE3C,OAAO;QACL,QAAQ,EAAE;YACR,KAAK,EAAE,GAAG;YACV,IAAI,EAAE,OAAgB;YACtB,QAAQ,EAAE,IAAI;YACd,WAAW,EAAE,iCAAiC;YAC9C,OAAO,EAAE,QAAQ;YACjB,OAAO,EAAE,QAAQ;YACjB,MAAM,EAAE,CAAC,MAAgB,EAAY,EAAE,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,oBAAoB;SACnF;QACD,SAAS,EAAE;YACT,KAAK,EAAE,GAAG;YACV,WAAW,EAAE,oDAAoD;YACjE,MAAM,EAAE,CAAC,YAAgC,EAAa,EAAE;gBACtD,IAAI;oBACF,OAAO,OAAO,YAAY,KAAK,QAAQ;wBACrC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC;wBAC1B,CAAC,CAAC,YAAY,CAAC;iBAClB;gBAAC,MAAM;oBACN,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;iBACtC;YACH,CAAC;YACD,QAAQ,EAAE,IAAI;SACf;QACD,IAAI,EAAE;YACJ,KAAK,EAAE,GAAG;YACV,WAAW,EAAE,wBAAwB;YACrC,OAAO,EAAE,oBAAoB;SAC9B;QACD,OAAO,EAAE;YACP,KAAK,EAAE,GAAG;YACV,WAAW,EACT,uEAAuE;YACzE,OAAO,EAAE,SAAS;YAClB,MAAM,EAAE,CACN,UAAkB,EACkC,EAAE;gBACtD,IAAI,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE;oBAChC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC;oBAC/C,6DAA6D;iBAC9D;qBAAM,IAAI,eAAe,CAAC,UAAU,CAAC,EAAE;oBACtC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC;iBACjD;gBACD,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;YACrC,CAAC;SACF;QACD,IAAI,EAAE;YACJ,KAAK,EAAE,GAAG;YACV,WAAW,EAAE,0BAA0B;YACvC,6EAA6E;YAC7E,OAAO,EAAE,WAA2B;YACpC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,oBAAY,CAAuB;SAC3D;QACD,QAAQ,EAAE;YACR,KAAK,EAAE,GAAG;YACV,WAAW,EAAE,sBAAsB;YACnC,6EAA6E;YAC7E,OAAO,EAAE,eAA2B;YACpC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,gBAAQ,CAAmB;SACnD;KACF,CAAC;AACJ,CAAC","sourcesContent":["import { platform } from 'node:os';\nimport { argv, stdout } from 'node:process';\nimport yargs from 'yargs/yargs';\nimport { normalizeSystemArchitecture } from './utils';\nimport {\n type Checksums,\n type ParsedOptions,\n type ArchitecturesTuple,\n type BinariesTuple,\n type PlatformsTuple,\n Architecture,\n Binary,\n Platform,\n} from './types';\n\nfunction isVersionString(value: string): value is `v${string}` {\n return /^v\\d/u.test(value);\n}\n\nexport function printBanner() {\n console.log(`\n.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx\n\n ╔═╗ ╔═╗ ╦ ╦ ╔╗╔ ╔╦╗ ╦═╗ ╦ ╦ Portable and modular toolkit\n ╠╣ ║ ║ ║ ║ ║║║ ║║ ╠╦╝ ╚╦╝ for Ethereum Application Development\n ╚ ╚═╝ ╚═╝ ╝╚╝ ═╩╝ ╩╚═ ╩ written in Rust.\n\n.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx\n\nRepo : https://github.com/foundry-rs/\nBook : https://book.getfoundry.sh/\nChat : https://t.me/foundry_rs/\nSupport : https://t.me/foundry_support/\nContribute : https://github.com/orgs/foundry-rs/projects/2/\n\n.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx\n`);\n}\n\nexport function parseArgs(args: string[] = argv.slice(2)) {\n const { $0, _, ...parsed } = yargs()\n // Ensure unrecognized commands/options are reported as errors.\n .strict()\n // disable yargs's version, as it doesn't make sense here\n .version(false)\n // use the scriptName in `--help` output\n .scriptName('yarn foundryup')\n // wrap output at a maximum of 120 characters or `stdout.columns`\n .wrap(Math.min(120, stdout.columns))\n .parserConfiguration({\n 'strip-aliased': true,\n 'strip-dashed': true,\n })\n // enable ENV parsing, which allows the user to specify foundryup options\n // via environment variables prefixed with `FOUNDRYUP_`\n .env('FOUNDRYUP')\n .command(['$0', 'install'], 'Install foundry binaries', (builder) => {\n builder.options(getOptions()).pkgConf('foundryup');\n })\n .command('cache', '', (builder) => {\n builder.command('clean', 'Remove the shared cache files').demandCommand();\n })\n .parseSync(args);\n\n const command = _.join(' ');\n if (command === 'cache clean') {\n return {\n command,\n } as const;\n }\n\n // if we get here `command` is always 'install' or '' (yargs checks it)\n return {\n command: 'install',\n options: parsed as ParsedOptions<ReturnType<typeof getOptions>>,\n } as const;\n}\n\nconst Binaries = Object.values(Binary) as BinariesTuple;\n\nfunction getOptions(\n defaultPlatform = platform(),\n defaultArch = normalizeSystemArchitecture(),\n) {\n return {\n binaries: {\n alias: 'b',\n type: 'array' as const,\n multiple: true,\n description: 'Specify the binaries to install',\n default: Binaries,\n choices: Binaries,\n coerce: (values: Binary[]): Binary[] => [...new Set(values)], // Remove duplicates\n },\n checksums: {\n alias: 'c',\n description: 'JSON object containing checksums for the binaries.',\n coerce: (rawChecksums: string | Checksums): Checksums => {\n try {\n return typeof rawChecksums === 'string'\n ? JSON.parse(rawChecksums)\n : rawChecksums;\n } catch {\n throw new Error('Invalid checksums');\n }\n },\n optional: true,\n },\n repo: {\n alias: 'r',\n description: 'Specify the repository',\n default: 'foundry-rs/foundry',\n },\n version: {\n alias: 'v',\n description:\n 'Specify the version (see: https://github.com/foundry-rs/foundry/tags)',\n default: 'nightly',\n coerce: (\n rawVersion: string,\n ): { version: 'nightly' | `v${string}`; tag: string } => {\n if (/^nightly/u.test(rawVersion)) {\n return { version: 'nightly', tag: rawVersion };\n // we don't validate the version much, we just trust the user\n } else if (isVersionString(rawVersion)) {\n return { version: rawVersion, tag: rawVersion };\n }\n throw new Error('Invalid version');\n },\n },\n arch: {\n alias: 'a',\n description: 'Specify the architecture',\n // if `defaultArch` is not a supported Architecture yargs will throw an error\n default: defaultArch as Architecture,\n choices: Object.values(Architecture) as ArchitecturesTuple,\n },\n platform: {\n alias: 'p',\n description: 'Specify the platform',\n // if `defaultPlatform` is not a supported Platform yargs will throw an error\n default: defaultPlatform as Platform,\n choices: Object.values(Platform) as PlatformsTuple,\n },\n };\n}\n"]}
1
+ {"version":3,"file":"options.cjs","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"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","sourcesContent":["import { platform } from 'node:os';\nimport { argv, stdout } from 'node:process';\nimport yargs from 'yargs/yargs';\n\nimport {\n type Checksums,\n type ParsedOptions,\n type ArchitecturesTuple,\n type BinariesTuple,\n type PlatformsTuple,\n Architecture,\n Binary,\n Platform,\n} from './types';\nimport { normalizeSystemArchitecture } from './utils';\n\n/**\n * Type guard to check if a string is a valid version string starting with 'v'.\n *\n * @param value - The string to check\n * @returns True if the string is a valid version string\n */\nfunction isVersionString(value: string): value is `v${string}` {\n return /^v\\d/u.test(value);\n}\n\n/**\n * Prints the Foundry banner to the console.\n */\nexport function printBanner() {\n console.log(`\n.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx\n\n ╔═╗ ╔═╗ ╦ ╦ ╔╗╔ ╔╦╗ ╦═╗ ╦ ╦ Portable and modular toolkit\n ╠╣ ║ ║ ║ ║ ║║║ ║║ ╠╦╝ ╚╦╝ for Ethereum Application Development\n ╚ ╚═╝ ╚═╝ ╝╚╝ ═╩╝ ╩╚═ ╩ written in Rust.\n\n.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx\n\nRepo : https://github.com/foundry-rs/\nBook : https://book.getfoundry.sh/\nChat : https://t.me/foundry_rs/\nSupport : https://t.me/foundry_support/\nContribute : https://github.com/orgs/foundry-rs/projects/2/\n\n.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx\n`);\n}\n\n/**\n * Parses command line arguments and returns the parsed options.\n *\n * @param args - Command line arguments to parse\n * @returns Parsed command line arguments\n */\nexport function parseArgs(args: string[] = argv.slice(2)) {\n const { $0, _, ...parsed } = yargs()\n // Ensure unrecognized commands/options are reported as errors.\n .strict()\n // disable yargs's version, as it doesn't make sense here\n .version(false)\n // use the scriptName in `--help` output\n .scriptName('yarn foundryup')\n // wrap output at a maximum of 120 characters or `stdout.columns`\n .wrap(Math.min(120, stdout.columns))\n .parserConfiguration({\n 'strip-aliased': true,\n 'strip-dashed': true,\n })\n // enable ENV parsing, which allows the user to specify foundryup options\n // via environment variables prefixed with `FOUNDRYUP_`\n .env('FOUNDRYUP')\n .command(['$0', 'install'], 'Install foundry binaries', (builder) => {\n builder.options(getOptions()).pkgConf('foundryup');\n })\n .command('cache', '', (builder) => {\n builder.command('clean', 'Remove the shared cache files').demandCommand();\n })\n .parseSync(args);\n\n const command = _.join(' ');\n if (command === 'cache clean') {\n return {\n command,\n } as const;\n }\n\n // if we get here `command` is always 'install' or '' (yargs checks it)\n return {\n command: 'install',\n options: parsed as ParsedOptions<ReturnType<typeof getOptions>>,\n } as const;\n}\n\nconst Binaries = Object.values(Binary) as BinariesTuple;\n\n/**\n * Returns the command line options configuration.\n *\n * @param defaultPlatform - Default platform to use\n * @param defaultArch - Default architecture to use\n * @returns Command line options configuration\n */\nfunction getOptions(\n defaultPlatform = platform(),\n defaultArch = normalizeSystemArchitecture(),\n) {\n return {\n binaries: {\n alias: 'b',\n type: 'array' as const,\n multiple: true,\n description: 'Specify the binaries to install',\n default: Binaries,\n choices: Binaries,\n coerce: (values: Binary[]): Binary[] => [...new Set(values)], // Remove duplicates\n },\n checksums: {\n alias: 'c',\n description: 'JSON object containing checksums for the binaries.',\n coerce: (rawChecksums: string | Checksums): Checksums => {\n try {\n return typeof rawChecksums === 'string'\n ? JSON.parse(rawChecksums)\n : rawChecksums;\n } catch {\n throw new Error('Invalid checksums');\n }\n },\n optional: true,\n },\n repo: {\n alias: 'r',\n description: 'Specify the repository',\n default: 'foundry-rs/foundry',\n },\n version: {\n alias: 'v',\n description:\n 'Specify the version (see: https://github.com/foundry-rs/foundry/tags)',\n default: 'nightly',\n coerce: (\n rawVersion: string,\n ): { version: 'nightly' | `v${string}`; tag: string } => {\n if (rawVersion.startsWith('nightly')) {\n return { version: 'nightly', tag: rawVersion };\n // we don't validate the version much, we just trust the user\n } else if (isVersionString(rawVersion)) {\n return { version: rawVersion, tag: rawVersion };\n }\n throw new Error('Invalid version');\n },\n },\n arch: {\n alias: 'a',\n description: 'Specify the architecture',\n // if `defaultArch` is not a supported Architecture yargs will throw an error\n default: defaultArch as Architecture,\n choices: Object.values(Architecture) as ArchitecturesTuple,\n },\n platform: {\n alias: 'p',\n description: 'Specify the platform',\n // if `defaultPlatform` is not a supported Platform yargs will throw an error\n default: defaultPlatform as Platform,\n choices: Object.values(Platform) as PlatformsTuple,\n },\n };\n}\n"]}
@@ -1,5 +1,14 @@
1
1
  import { type Checksums, type ParsedOptions, Architecture, Binary, Platform } from "./types.cjs";
2
+ /**
3
+ * Prints the Foundry banner to the console.
4
+ */
2
5
  export declare function printBanner(): void;
6
+ /**
7
+ * Parses command line arguments and returns the parsed options.
8
+ *
9
+ * @param args - Command line arguments to parse
10
+ * @returns Parsed command line arguments
11
+ */
3
12
  export declare function parseArgs(args?: string[]): {
4
13
  readonly command: "cache clean";
5
14
  readonly options?: undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"options.d.cts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,SAAS,EACd,KAAK,aAAa,EAIlB,YAAY,EACZ,MAAM,EACN,QAAQ,EACT,oBAAgB;AAMjB,wBAAgB,WAAW,SAkB1B;AAED,wBAAgB,SAAS,CAAC,IAAI,GAAE,MAAM,EAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqCvD"}
1
+ {"version":3,"file":"options.d.cts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,SAAS,EACd,KAAK,aAAa,EAIlB,YAAY,EACZ,MAAM,EACN,QAAQ,EACT,oBAAgB;AAajB;;GAEG;AACH,wBAAgB,WAAW,SAkB1B;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,GAAE,MAAM,EAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqCvD"}
@@ -1,5 +1,14 @@
1
1
  import { type Checksums, type ParsedOptions, Architecture, Binary, Platform } from "./types.mjs";
2
+ /**
3
+ * Prints the Foundry banner to the console.
4
+ */
2
5
  export declare function printBanner(): void;
6
+ /**
7
+ * Parses command line arguments and returns the parsed options.
8
+ *
9
+ * @param args - Command line arguments to parse
10
+ * @returns Parsed command line arguments
11
+ */
3
12
  export declare function parseArgs(args?: string[]): {
4
13
  readonly command: "cache clean";
5
14
  readonly options?: undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"options.d.mts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,SAAS,EACd,KAAK,aAAa,EAIlB,YAAY,EACZ,MAAM,EACN,QAAQ,EACT,oBAAgB;AAMjB,wBAAgB,WAAW,SAkB1B;AAED,wBAAgB,SAAS,CAAC,IAAI,GAAE,MAAM,EAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqCvD"}
1
+ {"version":3,"file":"options.d.mts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,KAAK,SAAS,EACd,KAAK,aAAa,EAIlB,YAAY,EACZ,MAAM,EACN,QAAQ,EACT,oBAAgB;AAajB;;GAEG;AACH,wBAAgB,WAAW,SAkB1B;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,GAAE,MAAM,EAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqCvD"}
package/dist/options.mjs CHANGED
@@ -1,11 +1,20 @@
1
1
  import { platform } from "node:os";
2
2
  import { argv, stdout } from "node:process";
3
3
  import yargs from "yargs/yargs";
4
- import { normalizeSystemArchitecture } from "./utils.mjs";
5
4
  import { Architecture, Binary, Platform } from "./types.mjs";
5
+ import { normalizeSystemArchitecture } from "./utils.mjs";
6
+ /**
7
+ * Type guard to check if a string is a valid version string starting with 'v'.
8
+ *
9
+ * @param value - The string to check
10
+ * @returns True if the string is a valid version string
11
+ */
6
12
  function isVersionString(value) {
7
13
  return /^v\d/u.test(value);
8
14
  }
15
+ /**
16
+ * Prints the Foundry banner to the console.
17
+ */
9
18
  export function printBanner() {
10
19
  console.log(`
11
20
  .xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx
@@ -25,6 +34,12 @@ Contribute : https://github.com/orgs/foundry-rs/projects/2/
25
34
  .xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx.xOx
26
35
  `);
27
36
  }
37
+ /**
38
+ * Parses command line arguments and returns the parsed options.
39
+ *
40
+ * @param args - Command line arguments to parse
41
+ * @returns Parsed command line arguments
42
+ */
28
43
  export function parseArgs(args = argv.slice(2)) {
29
44
  const { $0, _, ...parsed } = yargs()
30
45
  // Ensure unrecognized commands/options are reported as errors.
@@ -62,6 +77,13 @@ export function parseArgs(args = argv.slice(2)) {
62
77
  };
63
78
  }
64
79
  const Binaries = Object.values(Binary);
80
+ /**
81
+ * Returns the command line options configuration.
82
+ *
83
+ * @param defaultPlatform - Default platform to use
84
+ * @param defaultArch - Default architecture to use
85
+ * @returns Command line options configuration
86
+ */
65
87
  function getOptions(defaultPlatform = platform(), defaultArch = normalizeSystemArchitecture()) {
66
88
  return {
67
89
  binaries: {
@@ -98,7 +120,7 @@ function getOptions(defaultPlatform = platform(), defaultArch = normalizeSystemA
98
120
  description: 'Specify the version (see: https://github.com/foundry-rs/foundry/tags)',
99
121
  default: 'nightly',
100
122
  coerce: (rawVersion) => {
101
- if (/^nightly/u.test(rawVersion)) {
123
+ if (rawVersion.startsWith('nightly')) {
102
124
  return { version: 'nightly', tag: rawVersion };
103
125
  // we don't validate the version much, we just trust the user
104
126
  }