@socketsecurity/lib 5.2.1 → 5.4.0
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/CHANGELOG.md +30 -0
- package/dist/bin.d.ts +0 -9
- package/dist/bin.js +70 -48
- package/dist/constants/agents.js +2 -2
- package/dist/constants/platform.d.ts +21 -0
- package/dist/constants/platform.js +30 -6
- package/dist/cover/code.js +13 -5
- package/dist/debug.js +1 -1
- package/dist/dlx/binary.d.ts +1 -1
- package/dist/dlx/binary.js +49 -39
- package/dist/dlx/cache.js +10 -2
- package/dist/dlx/dir.js +1 -1
- package/dist/dlx/manifest.d.ts +2 -1
- package/dist/dlx/manifest.js +45 -41
- package/dist/dlx/package.js +39 -19
- package/dist/dlx/packages.js +1 -1
- package/dist/dlx/paths.js +1 -1
- package/dist/env/rewire.js +10 -2
- package/dist/external/@inquirer/checkbox.js +4 -2528
- package/dist/external/@inquirer/confirm.js +4 -2371
- package/dist/external/@inquirer/input.js +4 -2395
- package/dist/external/@inquirer/password.js +4 -2503
- package/dist/external/@inquirer/search.js +4 -2500
- package/dist/external/@inquirer/select.js +4 -2617
- package/dist/external/del.js +4 -7139
- package/dist/external/fast-glob.js +4 -5776
- package/dist/external/inquirer-pack.js +4610 -0
- package/dist/external/npm-core.js +3 -1
- package/dist/external/pico-pack.js +7162 -0
- package/dist/external/picomatch.js +4 -1523
- package/dist/external/spdx-correct.js +4 -1384
- package/dist/external/spdx-expression-parse.js +4 -1047
- package/dist/external/spdx-pack.js +1640 -0
- package/dist/external/validate-npm-package-name.js +4 -104
- package/dist/fs.js +3 -3
- package/dist/git.js +41 -38
- package/dist/http-request.js +12 -4
- package/dist/ipc.js +53 -29
- package/dist/json/edit.js +1 -1
- package/dist/json/format.js +1 -1
- package/dist/logger.js +1 -1
- package/dist/packages/edit.js +3 -3
- package/dist/packages/isolation.js +45 -23
- package/dist/packages/licenses.js +10 -2
- package/dist/paths/normalize.js +3 -3
- package/dist/paths/packages.js +1 -1
- package/dist/paths/socket.d.ts +2 -2
- package/dist/paths/socket.js +27 -21
- package/dist/process-lock.js +23 -14
- package/dist/promises.js +1 -1
- package/dist/releases/github.d.ts +82 -137
- package/dist/releases/github.js +91 -48
- package/dist/releases/socket-btm.d.ts +78 -192
- package/dist/releases/socket-btm.js +112 -50
- package/dist/signal-exit.js +1 -1
- package/dist/spawn.js +11 -4
- package/dist/stdio/mask.d.ts +6 -21
- package/dist/stdio/mask.js +18 -14
- package/dist/themes/context.js +10 -2
- package/package.json +3 -2
|
@@ -1,10 +1,53 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Pattern for matching release assets.
|
|
3
|
+
* Can be either:
|
|
4
|
+
* - A string with glob pattern syntax
|
|
5
|
+
* - A prefix/suffix pair for explicit matching (backward compatible)
|
|
6
|
+
* - A RegExp for complex patterns
|
|
7
|
+
*
|
|
8
|
+
* String patterns support full glob syntax via picomatch.
|
|
9
|
+
* Examples:
|
|
10
|
+
* - Simple wildcard: yoga-sync-*.mjs matches yoga-sync-abc123.mjs
|
|
11
|
+
* - Complex: models-*.tar.gz matches models-2024-01-15.tar.gz
|
|
12
|
+
* - Prefix wildcard: *-models.tar.gz matches foo-models.tar.gz
|
|
13
|
+
* - Suffix wildcard: yoga-* matches yoga-layout
|
|
14
|
+
* - Brace expansion: {yoga,models}-*.{mjs,js} matches yoga-abc.mjs or models-xyz.js
|
|
15
|
+
*
|
|
16
|
+
* For backward compatibility, prefix/suffix objects are still supported but glob patterns are recommended.
|
|
3
17
|
*/
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
};
|
|
18
|
+
export type AssetPattern = string | {
|
|
19
|
+
prefix: string;
|
|
20
|
+
suffix: string;
|
|
21
|
+
} | RegExp;
|
|
22
|
+
/**
|
|
23
|
+
* Configuration for downloading a GitHub release.
|
|
24
|
+
*/
|
|
25
|
+
export interface DownloadGitHubReleaseConfig {
|
|
26
|
+
/** Asset name on GitHub. */
|
|
27
|
+
assetName: string;
|
|
28
|
+
/** Binary filename (e.g., 'node', 'binject'). */
|
|
29
|
+
binaryName: string;
|
|
30
|
+
/** Working directory (defaults to process.cwd()). */
|
|
31
|
+
cwd?: string;
|
|
32
|
+
/** Download destination directory. @default 'build/downloaded' */
|
|
33
|
+
downloadDir?: string;
|
|
34
|
+
/** GitHub repository owner/organization. */
|
|
35
|
+
owner: string;
|
|
36
|
+
/** Platform-arch identifier (e.g., 'linux-x64-musl'). */
|
|
37
|
+
platformArch: string;
|
|
38
|
+
/** Suppress log messages. @default false */
|
|
39
|
+
quiet?: boolean;
|
|
40
|
+
/** Remove macOS quarantine attribute after download. @default true */
|
|
41
|
+
removeMacOSQuarantine?: boolean;
|
|
42
|
+
/** GitHub repository name. */
|
|
43
|
+
repo: string;
|
|
44
|
+
/** Specific release tag to download. */
|
|
45
|
+
tag?: string;
|
|
46
|
+
/** Tool name for directory structure. */
|
|
47
|
+
toolName: string;
|
|
48
|
+
/** Tool prefix for finding latest release. */
|
|
49
|
+
toolPrefix?: string;
|
|
50
|
+
}
|
|
8
51
|
/**
|
|
9
52
|
* Configuration for repository access.
|
|
10
53
|
*/
|
|
@@ -19,161 +62,63 @@ export interface RepoConfig {
|
|
|
19
62
|
repo: string;
|
|
20
63
|
}
|
|
21
64
|
/**
|
|
22
|
-
*
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
65
|
+
* Socket-btm GitHub repository configuration.
|
|
66
|
+
*/
|
|
67
|
+
export declare const SOCKET_BTM_REPO: {
|
|
68
|
+
readonly owner: "SocketDev";
|
|
69
|
+
readonly repo: "socket-btm";
|
|
70
|
+
};
|
|
71
|
+
/**
|
|
72
|
+
* Download a specific release asset.
|
|
73
|
+
* Supports pattern matching for dynamic asset discovery.
|
|
27
74
|
*
|
|
28
|
-
* @param
|
|
75
|
+
* @param tag - Release tag name
|
|
76
|
+
* @param assetPattern - Asset name or pattern (glob string, prefix/suffix object, or RegExp)
|
|
77
|
+
* @param outputPath - Path to write the downloaded file
|
|
29
78
|
* @param repoConfig - Repository configuration (owner/repo)
|
|
30
79
|
* @param options - Additional options
|
|
31
|
-
* @returns Latest release tag or null if not found
|
|
32
|
-
*
|
|
33
|
-
* @example
|
|
34
|
-
* ```ts
|
|
35
|
-
* const tag = await getLatestRelease('node-smol-', {
|
|
36
|
-
* owner: 'SocketDev',
|
|
37
|
-
* repo: 'socket-btm'
|
|
38
|
-
* })
|
|
39
|
-
* // Returns: 'node-smol-20260105-c47753c'
|
|
40
|
-
* ```
|
|
41
80
|
*/
|
|
42
|
-
export declare function
|
|
81
|
+
export declare function downloadReleaseAsset(tag: string, assetPattern: string | AssetPattern, outputPath: string, repoConfig: RepoConfig, options?: {
|
|
43
82
|
quiet?: boolean;
|
|
44
|
-
}): Promise<
|
|
83
|
+
}): Promise<void>;
|
|
45
84
|
/**
|
|
46
|
-
* Get
|
|
85
|
+
* Get GitHub authentication headers if token is available.
|
|
86
|
+
* Checks GH_TOKEN or GITHUB_TOKEN environment variables.
|
|
87
|
+
*
|
|
88
|
+
* @returns Headers object with Authorization header if token exists.
|
|
89
|
+
*/
|
|
90
|
+
export declare function getAuthHeaders(): Record<string, string>;
|
|
91
|
+
/**
|
|
92
|
+
* Get latest release tag matching a tool prefix.
|
|
93
|
+
* Optionally filter by releases containing a matching asset.
|
|
47
94
|
*
|
|
48
|
-
* @param
|
|
49
|
-
* @param assetName - Asset name to download (e.g., 'node-linux-x64-musl')
|
|
95
|
+
* @param toolPrefix - Tool name prefix to search for (e.g., 'node-smol-')
|
|
50
96
|
* @param repoConfig - Repository configuration (owner/repo)
|
|
51
97
|
* @param options - Additional options
|
|
52
|
-
* @
|
|
53
|
-
*
|
|
54
|
-
* @example
|
|
55
|
-
* ```ts
|
|
56
|
-
* const url = await getReleaseAssetUrl(
|
|
57
|
-
* 'node-smol-20260105-c47753c',
|
|
58
|
-
* 'node-linux-x64-musl',
|
|
59
|
-
* { owner: 'SocketDev', repo: 'socket-btm' }
|
|
60
|
-
* )
|
|
61
|
-
* ```
|
|
98
|
+
* @param options.assetPattern - Optional pattern to filter releases by matching asset
|
|
99
|
+
* @returns Latest release tag or null if not found
|
|
62
100
|
*/
|
|
63
|
-
export declare function
|
|
101
|
+
export declare function getLatestRelease(toolPrefix: string, repoConfig: RepoConfig, options?: {
|
|
102
|
+
assetPattern?: AssetPattern;
|
|
64
103
|
quiet?: boolean;
|
|
65
104
|
}): Promise<string | null>;
|
|
66
105
|
/**
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* Uses browser_download_url to avoid consuming GitHub API quota.
|
|
70
|
-
* Automatically follows redirects and retries on failure.
|
|
106
|
+
* Get download URL for a specific release asset.
|
|
107
|
+
* Supports pattern matching for dynamic asset discovery.
|
|
71
108
|
*
|
|
72
109
|
* @param tag - Release tag name
|
|
73
|
-
* @param
|
|
74
|
-
* @param outputPath - Path to write the downloaded file
|
|
110
|
+
* @param assetPattern - Asset name or pattern (glob string, prefix/suffix object, or RegExp)
|
|
75
111
|
* @param repoConfig - Repository configuration (owner/repo)
|
|
76
112
|
* @param options - Additional options
|
|
77
|
-
*
|
|
78
|
-
* @example
|
|
79
|
-
* ```ts
|
|
80
|
-
* await downloadReleaseAsset(
|
|
81
|
-
* 'node-smol-20260105-c47753c',
|
|
82
|
-
* 'node-linux-x64-musl',
|
|
83
|
-
* '/path/to/output/node',
|
|
84
|
-
* { owner: 'SocketDev', repo: 'socket-btm' }
|
|
85
|
-
* )
|
|
86
|
-
* ```
|
|
113
|
+
* @returns Browser download URL for the asset
|
|
87
114
|
*/
|
|
88
|
-
export declare function
|
|
115
|
+
export declare function getReleaseAssetUrl(tag: string, assetPattern: string | AssetPattern, repoConfig: RepoConfig, options?: {
|
|
89
116
|
quiet?: boolean;
|
|
90
|
-
}): Promise<
|
|
91
|
-
/**
|
|
92
|
-
* Configuration for downloading a GitHub release.
|
|
93
|
-
*/
|
|
94
|
-
export interface DownloadGitHubReleaseConfig {
|
|
95
|
-
/**
|
|
96
|
-
* GitHub repository owner/organization.
|
|
97
|
-
*/
|
|
98
|
-
owner: string;
|
|
99
|
-
/**
|
|
100
|
-
* GitHub repository name.
|
|
101
|
-
*/
|
|
102
|
-
repo: string;
|
|
103
|
-
/**
|
|
104
|
-
* Working directory (defaults to process.cwd()).
|
|
105
|
-
* Used to resolve relative paths in downloadDir.
|
|
106
|
-
*/
|
|
107
|
-
cwd?: string;
|
|
108
|
-
/**
|
|
109
|
-
* Download destination directory.
|
|
110
|
-
* Can be absolute or relative to cwd.
|
|
111
|
-
* @default 'build/downloaded' (relative to cwd)
|
|
112
|
-
*/
|
|
113
|
-
downloadDir?: string;
|
|
114
|
-
/**
|
|
115
|
-
* Tool name for directory structure (e.g., 'node-smol', 'binject', 'lief').
|
|
116
|
-
* Creates subdirectory: {downloadDir}/{toolName}/{platformArch}/
|
|
117
|
-
*/
|
|
118
|
-
toolName: string;
|
|
119
|
-
/**
|
|
120
|
-
* Platform-arch identifier (e.g., 'linux-x64-musl', 'darwin-arm64').
|
|
121
|
-
* Used for the download directory path.
|
|
122
|
-
*/
|
|
123
|
-
platformArch: string;
|
|
124
|
-
/**
|
|
125
|
-
* Binary filename (e.g., 'node', 'binject', 'lief', 'node.exe').
|
|
126
|
-
*/
|
|
127
|
-
binaryName: string;
|
|
128
|
-
/**
|
|
129
|
-
* Asset name on GitHub (e.g., 'node-linux-x64-musl', 'binject-darwin-arm64').
|
|
130
|
-
*/
|
|
131
|
-
assetName: string;
|
|
132
|
-
/**
|
|
133
|
-
* Tool prefix for finding latest release (e.g., 'node-smol-', 'binject-').
|
|
134
|
-
* Either this or `tag` must be provided.
|
|
135
|
-
*/
|
|
136
|
-
toolPrefix?: string;
|
|
137
|
-
/**
|
|
138
|
-
* Specific release tag to download (e.g., 'node-smol-20260105-c47753c').
|
|
139
|
-
* If not provided, uses `toolPrefix` to find the latest release.
|
|
140
|
-
*/
|
|
141
|
-
tag?: string;
|
|
142
|
-
/**
|
|
143
|
-
* Suppress log messages.
|
|
144
|
-
* @default false
|
|
145
|
-
*/
|
|
146
|
-
quiet?: boolean;
|
|
147
|
-
/**
|
|
148
|
-
* Remove macOS quarantine attribute after download.
|
|
149
|
-
* Only applies when downloading on macOS for macOS binaries.
|
|
150
|
-
* @default true
|
|
151
|
-
*/
|
|
152
|
-
removeMacOSQuarantine?: boolean;
|
|
153
|
-
}
|
|
117
|
+
}): Promise<string | null>;
|
|
154
118
|
/**
|
|
155
119
|
* Download a binary from any GitHub repository with version caching.
|
|
156
120
|
*
|
|
157
|
-
* Downloads to: `{downloadDir}/{toolName}/{platformArch}/{binaryName}`
|
|
158
|
-
* Caches version in: `{downloadDir}/{toolName}/{platformArch}/.version`
|
|
159
|
-
*
|
|
160
121
|
* @param config - Download configuration
|
|
161
122
|
* @returns Path to the downloaded binary
|
|
162
|
-
*
|
|
163
|
-
* @example
|
|
164
|
-
* ```ts
|
|
165
|
-
* // Download from any GitHub repo
|
|
166
|
-
* const nodePath = await downloadGitHubRelease({
|
|
167
|
-
* owner: 'nodejs',
|
|
168
|
-
* repo: 'node',
|
|
169
|
-
* cwd: process.cwd(),
|
|
170
|
-
* downloadDir: 'build/downloaded', // relative to cwd
|
|
171
|
-
* toolName: 'node',
|
|
172
|
-
* platformArch: 'linux-x64',
|
|
173
|
-
* binaryName: 'node',
|
|
174
|
-
* assetName: 'node-v20.10.0-linux-x64.tar.gz',
|
|
175
|
-
* tag: 'v20.10.0'
|
|
176
|
-
* })
|
|
177
|
-
* ```
|
|
178
123
|
*/
|
|
179
124
|
export declare function downloadGitHubRelease(config: DownloadGitHubReleaseConfig): Promise<string>;
|
package/dist/releases/github.js
CHANGED
|
@@ -32,23 +32,18 @@ __export(github_exports, {
|
|
|
32
32
|
SOCKET_BTM_REPO: () => SOCKET_BTM_REPO,
|
|
33
33
|
downloadGitHubRelease: () => downloadGitHubRelease,
|
|
34
34
|
downloadReleaseAsset: () => downloadReleaseAsset,
|
|
35
|
+
getAuthHeaders: () => getAuthHeaders,
|
|
35
36
|
getLatestRelease: () => getLatestRelease,
|
|
36
37
|
getReleaseAssetUrl: () => getReleaseAssetUrl
|
|
37
38
|
});
|
|
38
39
|
module.exports = __toCommonJS(github_exports);
|
|
39
|
-
var
|
|
40
|
-
var import_promises = require("node:fs/promises");
|
|
41
|
-
var import_node_path = __toESM(require("node:path"));
|
|
40
|
+
var import_picomatch = __toESM(require("../external/picomatch.js"));
|
|
42
41
|
var import_fs = require("../fs.js");
|
|
43
42
|
var import_http_request = require("../http-request.js");
|
|
44
43
|
var import_logger = require("../logger.js");
|
|
45
|
-
var
|
|
44
|
+
var import_promises = require("../promises.js");
|
|
46
45
|
var import_spawn = require("../spawn.js");
|
|
47
46
|
const logger = (0, import_logger.getDefaultLogger)();
|
|
48
|
-
const SOCKET_BTM_REPO = {
|
|
49
|
-
owner: "SocketDev",
|
|
50
|
-
repo: "socket-btm"
|
|
51
|
-
};
|
|
52
47
|
const RETRY_CONFIG = Object.freeze({
|
|
53
48
|
__proto__: null,
|
|
54
49
|
// Exponential backoff: delay doubles with each retry (5s, 10s, 20s).
|
|
@@ -58,6 +53,59 @@ const RETRY_CONFIG = Object.freeze({
|
|
|
58
53
|
// Maximum number of retry attempts (excluding initial request).
|
|
59
54
|
retries: 2
|
|
60
55
|
});
|
|
56
|
+
let _fs;
|
|
57
|
+
let _path;
|
|
58
|
+
function createMatcher(pattern) {
|
|
59
|
+
if (typeof pattern === "string") {
|
|
60
|
+
const isMatch = (0, import_picomatch.default)(pattern);
|
|
61
|
+
return (input) => isMatch(input);
|
|
62
|
+
}
|
|
63
|
+
if (pattern instanceof RegExp) {
|
|
64
|
+
return (input) => pattern.test(input);
|
|
65
|
+
}
|
|
66
|
+
const { prefix, suffix } = pattern;
|
|
67
|
+
return (input) => input.startsWith(prefix) && input.endsWith(suffix);
|
|
68
|
+
}
|
|
69
|
+
// @__NO_SIDE_EFFECTS__
|
|
70
|
+
function getFs() {
|
|
71
|
+
if (_fs === void 0) {
|
|
72
|
+
_fs = require("fs");
|
|
73
|
+
}
|
|
74
|
+
return _fs;
|
|
75
|
+
}
|
|
76
|
+
// @__NO_SIDE_EFFECTS__
|
|
77
|
+
function getPath() {
|
|
78
|
+
if (_path === void 0) {
|
|
79
|
+
_path = require("path");
|
|
80
|
+
}
|
|
81
|
+
return _path;
|
|
82
|
+
}
|
|
83
|
+
const SOCKET_BTM_REPO = {
|
|
84
|
+
owner: "SocketDev",
|
|
85
|
+
repo: "socket-btm"
|
|
86
|
+
};
|
|
87
|
+
async function downloadReleaseAsset(tag, assetPattern, outputPath, repoConfig, options = {}) {
|
|
88
|
+
const { owner, repo } = repoConfig;
|
|
89
|
+
const { quiet = false } = options;
|
|
90
|
+
const downloadUrl = await getReleaseAssetUrl(
|
|
91
|
+
tag,
|
|
92
|
+
assetPattern,
|
|
93
|
+
{ owner, repo },
|
|
94
|
+
{ quiet }
|
|
95
|
+
);
|
|
96
|
+
if (!downloadUrl) {
|
|
97
|
+
const patternDesc = typeof assetPattern === "string" ? assetPattern : "matching pattern";
|
|
98
|
+
throw new Error(`Asset ${patternDesc} not found in release ${tag}`);
|
|
99
|
+
}
|
|
100
|
+
const path = /* @__PURE__ */ getPath();
|
|
101
|
+
await (0, import_fs.safeMkdir)(path.dirname(outputPath));
|
|
102
|
+
await (0, import_http_request.httpDownload)(downloadUrl, outputPath, {
|
|
103
|
+
logger: quiet ? void 0 : logger,
|
|
104
|
+
progressInterval: 10,
|
|
105
|
+
retries: 2,
|
|
106
|
+
retryDelay: 5e3
|
|
107
|
+
});
|
|
108
|
+
}
|
|
61
109
|
function getAuthHeaders() {
|
|
62
110
|
const token = process.env["GH_TOKEN"] || process.env["GITHUB_TOKEN"];
|
|
63
111
|
const headers = {
|
|
@@ -70,9 +118,10 @@ function getAuthHeaders() {
|
|
|
70
118
|
return headers;
|
|
71
119
|
}
|
|
72
120
|
async function getLatestRelease(toolPrefix, repoConfig, options = {}) {
|
|
121
|
+
const { assetPattern, quiet = false } = options;
|
|
73
122
|
const { owner, repo } = repoConfig;
|
|
74
|
-
const
|
|
75
|
-
return await (0,
|
|
123
|
+
const isMatch = assetPattern ? createMatcher(assetPattern) : void 0;
|
|
124
|
+
return await (0, import_promises.pRetry)(
|
|
76
125
|
async () => {
|
|
77
126
|
const response = await (0, import_http_request.httpRequest)(
|
|
78
127
|
`https://api.github.com/repos/${owner}/${repo}/releases?per_page=100`,
|
|
@@ -85,13 +134,22 @@ async function getLatestRelease(toolPrefix, repoConfig, options = {}) {
|
|
|
85
134
|
}
|
|
86
135
|
const releases = JSON.parse(response.body.toString("utf8"));
|
|
87
136
|
for (const release of releases) {
|
|
88
|
-
const { tag_name: tag } = release;
|
|
89
|
-
if (tag.startsWith(toolPrefix)) {
|
|
90
|
-
|
|
91
|
-
|
|
137
|
+
const { assets, tag_name: tag } = release;
|
|
138
|
+
if (!tag.startsWith(toolPrefix)) {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (isMatch) {
|
|
142
|
+
const hasMatchingAsset = assets.some(
|
|
143
|
+
(a) => isMatch(a.name)
|
|
144
|
+
);
|
|
145
|
+
if (!hasMatchingAsset) {
|
|
146
|
+
continue;
|
|
92
147
|
}
|
|
93
|
-
return tag;
|
|
94
148
|
}
|
|
149
|
+
if (!quiet) {
|
|
150
|
+
logger.info(`Found release: ${tag}`);
|
|
151
|
+
}
|
|
152
|
+
return tag;
|
|
95
153
|
}
|
|
96
154
|
if (!quiet) {
|
|
97
155
|
logger.info(`No ${toolPrefix} release found in latest 100 releases`);
|
|
@@ -114,10 +172,11 @@ async function getLatestRelease(toolPrefix, repoConfig, options = {}) {
|
|
|
114
172
|
}
|
|
115
173
|
);
|
|
116
174
|
}
|
|
117
|
-
async function getReleaseAssetUrl(tag,
|
|
175
|
+
async function getReleaseAssetUrl(tag, assetPattern, repoConfig, options = {}) {
|
|
118
176
|
const { owner, repo } = repoConfig;
|
|
119
177
|
const { quiet = false } = options;
|
|
120
|
-
|
|
178
|
+
const isMatch = typeof assetPattern === "string" && !assetPattern.includes("*") && !assetPattern.includes("{") ? (input) => input === assetPattern : createMatcher(assetPattern);
|
|
179
|
+
return await (0, import_promises.pRetry)(
|
|
121
180
|
async () => {
|
|
122
181
|
const response = await (0, import_http_request.httpRequest)(
|
|
123
182
|
`https://api.github.com/repos/${owner}/${repo}/releases/tags/${tag}`,
|
|
@@ -130,13 +189,14 @@ async function getReleaseAssetUrl(tag, assetName, repoConfig, options = {}) {
|
|
|
130
189
|
}
|
|
131
190
|
const release = JSON.parse(response.body.toString("utf8"));
|
|
132
191
|
const asset = release.assets.find(
|
|
133
|
-
(a) => a.name
|
|
192
|
+
(a) => isMatch(a.name)
|
|
134
193
|
);
|
|
135
194
|
if (!asset) {
|
|
136
|
-
|
|
195
|
+
const patternDesc = typeof assetPattern === "string" ? assetPattern : "matching pattern";
|
|
196
|
+
throw new Error(`Asset ${patternDesc} not found in release ${tag}`);
|
|
137
197
|
}
|
|
138
198
|
if (!quiet) {
|
|
139
|
-
logger.info(`Found asset: ${
|
|
199
|
+
logger.info(`Found asset: ${asset.name}`);
|
|
140
200
|
}
|
|
141
201
|
return asset.browser_download_url;
|
|
142
202
|
},
|
|
@@ -156,26 +216,6 @@ async function getReleaseAssetUrl(tag, assetName, repoConfig, options = {}) {
|
|
|
156
216
|
}
|
|
157
217
|
);
|
|
158
218
|
}
|
|
159
|
-
async function downloadReleaseAsset(tag, assetName, outputPath, repoConfig, options = {}) {
|
|
160
|
-
const { owner, repo } = repoConfig;
|
|
161
|
-
const { quiet = false } = options;
|
|
162
|
-
const downloadUrl = await getReleaseAssetUrl(
|
|
163
|
-
tag,
|
|
164
|
-
assetName,
|
|
165
|
-
{ owner, repo },
|
|
166
|
-
{ quiet }
|
|
167
|
-
);
|
|
168
|
-
if (!downloadUrl) {
|
|
169
|
-
throw new Error(`Asset ${assetName} not found in release ${tag}`);
|
|
170
|
-
}
|
|
171
|
-
await (0, import_fs.safeMkdir)(import_node_path.default.dirname(outputPath));
|
|
172
|
-
await (0, import_http_request.httpDownload)(downloadUrl, outputPath, {
|
|
173
|
-
logger: quiet ? void 0 : logger,
|
|
174
|
-
progressInterval: 10,
|
|
175
|
-
retries: 2,
|
|
176
|
-
retryDelay: 5e3
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
219
|
async function downloadGitHubRelease(config) {
|
|
180
220
|
const {
|
|
181
221
|
assetName,
|
|
@@ -207,12 +247,14 @@ async function downloadGitHubRelease(config) {
|
|
|
207
247
|
} else {
|
|
208
248
|
throw new Error("Either toolPrefix or tag must be provided");
|
|
209
249
|
}
|
|
210
|
-
const
|
|
211
|
-
const
|
|
212
|
-
const
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
|
|
250
|
+
const path = /* @__PURE__ */ getPath();
|
|
251
|
+
const resolvedDownloadDir = path.isAbsolute(downloadDir) ? downloadDir : path.join(cwd, downloadDir);
|
|
252
|
+
const binaryDir = path.join(resolvedDownloadDir, toolName, platformArch);
|
|
253
|
+
const binaryPath = path.join(binaryDir, binaryName);
|
|
254
|
+
const versionPath = path.join(binaryDir, ".version");
|
|
255
|
+
const fs = /* @__PURE__ */ getFs();
|
|
256
|
+
if (fs.existsSync(versionPath) && fs.existsSync(binaryPath)) {
|
|
257
|
+
const cachedVersion = (await fs.promises.readFile(versionPath, "utf8")).trim();
|
|
216
258
|
if (cachedVersion === tag) {
|
|
217
259
|
if (!quiet) {
|
|
218
260
|
logger.info(`Using cached ${toolName} (${platformArch}): ${binaryPath}`);
|
|
@@ -232,7 +274,7 @@ async function downloadGitHubRelease(config) {
|
|
|
232
274
|
);
|
|
233
275
|
const isWindows = binaryName.endsWith(".exe");
|
|
234
276
|
if (!isWindows) {
|
|
235
|
-
|
|
277
|
+
fs.chmodSync(binaryPath, 493);
|
|
236
278
|
if (removeMacOSQuarantine && process.platform === "darwin" && platformArch.startsWith("darwin")) {
|
|
237
279
|
try {
|
|
238
280
|
await (0, import_spawn.spawn)("xattr", ["-d", "com.apple.quarantine", binaryPath], {
|
|
@@ -242,7 +284,7 @@ async function downloadGitHubRelease(config) {
|
|
|
242
284
|
}
|
|
243
285
|
}
|
|
244
286
|
}
|
|
245
|
-
await
|
|
287
|
+
await fs.promises.writeFile(versionPath, tag, "utf8");
|
|
246
288
|
if (!quiet) {
|
|
247
289
|
logger.info(`Downloaded ${toolName} to ${binaryPath}`);
|
|
248
290
|
}
|
|
@@ -253,6 +295,7 @@ async function downloadGitHubRelease(config) {
|
|
|
253
295
|
SOCKET_BTM_REPO,
|
|
254
296
|
downloadGitHubRelease,
|
|
255
297
|
downloadReleaseAsset,
|
|
298
|
+
getAuthHeaders,
|
|
256
299
|
getLatestRelease,
|
|
257
300
|
getReleaseAssetUrl
|
|
258
301
|
});
|