@socketsecurity/cli 1.1.102 ā 1.1.152
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 +278 -3
- package/DISCLOSURE +45 -0
- package/README.md +9 -0
- package/bin/cli.js +33 -1
- package/dist/cli.js +6598 -1912
- package/dist/cli.js.map +1 -1
- package/dist/constants.js +8 -10
- package/dist/constants.js.map +1 -1
- package/dist/init.gradle +73 -0
- package/dist/manifest-scripts/maven-extension/coana-maven-extension.jar +0 -0
- package/dist/manifest-scripts/socket-facts.init.gradle +581 -0
- package/dist/manifest-scripts/socket-facts.plugin.scala +544 -0
- package/dist/shadow-npm-bin2.js +6 -6
- package/dist/shadow-npm-bin2.js.map +1 -1
- package/dist/shadow-npm-inject.js +10 -10
- package/dist/shadow-npm-inject.js.map +1 -1
- package/dist/shadow-pnpm-bin2.js +13 -13
- package/dist/shadow-pnpm-bin2.js.map +1 -1
- package/dist/shadow-yarn-bin.js +3 -3
- package/dist/shadow-yarn-bin.js.map +1 -1
- package/dist/socket-completion.bash +0 -0
- package/dist/tsconfig.dts.tsbuildinfo +1 -1
- package/dist/types/commands/audit-log/output-audit-log.d.mts.map +1 -1
- package/dist/types/commands/ci/fetch-default-org-slug.d.mts.map +1 -1
- package/dist/types/commands/ci/handle-ci.d.mts.map +1 -1
- package/dist/types/commands/config/handle-config-get.d.mts.map +1 -1
- package/dist/types/commands/config/handle-config-set.d.mts.map +1 -1
- package/dist/types/commands/config/output-config-set.d.mts.map +1 -1
- package/dist/types/commands/fix/cmd-fix.d.mts.map +1 -1
- package/dist/types/commands/fix/coana-fix.d.mts.map +1 -1
- package/dist/types/commands/fix/handle-fix.d.mts +1 -1
- package/dist/types/commands/fix/handle-fix.d.mts.map +1 -1
- package/dist/types/commands/fix/types.d.mts +1 -0
- package/dist/types/commands/fix/types.d.mts.map +1 -1
- package/dist/types/commands/manifest/bazel/bazel-cquery.d.mts +70 -0
- package/dist/types/commands/manifest/bazel/bazel-cquery.d.mts.map +1 -0
- package/dist/types/commands/manifest/bazel/bazel-pypi-discovery.d.mts +44 -0
- package/dist/types/commands/manifest/bazel/bazel-pypi-discovery.d.mts.map +1 -0
- package/dist/types/commands/manifest/bazel/bazel-pypi-parser.d.mts +46 -0
- package/dist/types/commands/manifest/bazel/bazel-pypi-parser.d.mts.map +1 -0
- package/dist/types/commands/manifest/bazel/bazel-query-runner.d.mts +66 -8
- package/dist/types/commands/manifest/bazel/bazel-query-runner.d.mts.map +1 -1
- package/dist/types/commands/manifest/bazel/bazel-repo-discovery.d.mts +69 -29
- package/dist/types/commands/manifest/bazel/bazel-repo-discovery.d.mts.map +1 -1
- package/dist/types/commands/manifest/bazel/bazel-workspace-walk.d.mts +18 -0
- package/dist/types/commands/manifest/bazel/bazel-workspace-walk.d.mts.map +1 -0
- package/dist/types/commands/manifest/bazel/cmd-manifest-bazel.d.mts +26 -0
- package/dist/types/commands/manifest/bazel/cmd-manifest-bazel.d.mts.map +1 -1
- package/dist/types/commands/manifest/bazel/extract_bazel_to_maven.d.mts +110 -7
- package/dist/types/commands/manifest/bazel/extract_bazel_to_maven.d.mts.map +1 -1
- package/dist/types/commands/manifest/bazel/extract_bazel_to_pypi.d.mts +20 -0
- package/dist/types/commands/manifest/bazel/extract_bazel_to_pypi.d.mts.map +1 -0
- package/dist/types/commands/manifest/cmd-manifest-auto.d.mts.map +1 -1
- package/dist/types/commands/manifest/cmd-manifest-gradle.d.mts.map +1 -1
- package/dist/types/commands/manifest/cmd-manifest-kotlin.d.mts.map +1 -1
- package/dist/types/commands/manifest/cmd-manifest-maven.d.mts +9 -0
- package/dist/types/commands/manifest/cmd-manifest-maven.d.mts.map +1 -0
- package/dist/types/commands/manifest/cmd-manifest-scala.d.mts.map +1 -1
- package/dist/types/commands/manifest/cmd-manifest.d.mts.map +1 -1
- package/dist/types/commands/manifest/convert-gradle-to-facts.d.mts +9 -1
- package/dist/types/commands/manifest/convert-gradle-to-facts.d.mts.map +1 -1
- package/dist/types/commands/manifest/convert-maven-to-facts.d.mts +15 -0
- package/dist/types/commands/manifest/convert-maven-to-facts.d.mts.map +1 -0
- package/dist/types/commands/manifest/convert-sbt-to-facts.d.mts +19 -0
- package/dist/types/commands/manifest/convert-sbt-to-facts.d.mts.map +1 -0
- package/dist/types/commands/manifest/convert_gradle_to_maven.d.mts +2 -1
- package/dist/types/commands/manifest/convert_gradle_to_maven.d.mts.map +1 -1
- package/dist/types/commands/manifest/detect-manifest-actions.d.mts +1 -0
- package/dist/types/commands/manifest/detect-manifest-actions.d.mts.map +1 -1
- package/dist/types/commands/manifest/generate_auto_manifest.d.mts +12 -1
- package/dist/types/commands/manifest/generate_auto_manifest.d.mts.map +1 -1
- package/dist/types/commands/manifest/parse-build-tool-opts.d.mts +9 -0
- package/dist/types/commands/manifest/parse-build-tool-opts.d.mts.map +1 -0
- package/dist/types/commands/manifest/run-manifest-facts.d.mts +24 -0
- package/dist/types/commands/manifest/run-manifest-facts.d.mts.map +1 -0
- package/dist/types/commands/manifest/scripts/assemble.d.mts +16 -0
- package/dist/types/commands/manifest/scripts/assemble.d.mts.map +1 -0
- package/dist/types/commands/manifest/scripts/build-tool.d.mts +3 -0
- package/dist/types/commands/manifest/scripts/build-tool.d.mts.map +1 -0
- package/dist/types/commands/manifest/scripts/facts.d.mts +46 -0
- package/dist/types/commands/manifest/scripts/facts.d.mts.map +1 -0
- package/dist/types/commands/manifest/scripts/records.d.mts +66 -0
- package/dist/types/commands/manifest/scripts/records.d.mts.map +1 -0
- package/dist/types/commands/manifest/scripts/resolution-report-gradle.d.mts +10 -0
- package/dist/types/commands/manifest/scripts/resolution-report-gradle.d.mts.map +1 -0
- package/dist/types/commands/manifest/scripts/resolution-report-ivy.d.mts +7 -0
- package/dist/types/commands/manifest/scripts/resolution-report-ivy.d.mts.map +1 -0
- package/dist/types/commands/manifest/scripts/resolution-report-maven.d.mts +8 -0
- package/dist/types/commands/manifest/scripts/resolution-report-maven.d.mts.map +1 -0
- package/dist/types/commands/manifest/scripts/resolution-report-render.d.mts +43 -0
- package/dist/types/commands/manifest/scripts/resolution-report-render.d.mts.map +1 -0
- package/dist/types/commands/manifest/scripts/resolution-report.d.mts +18 -0
- package/dist/types/commands/manifest/scripts/resolution-report.d.mts.map +1 -0
- package/dist/types/commands/manifest/scripts/run.d.mts +43 -0
- package/dist/types/commands/manifest/scripts/run.d.mts.map +1 -0
- package/dist/types/commands/manifest/scripts/sidecar.d.mts +27 -0
- package/dist/types/commands/manifest/scripts/sidecar.d.mts.map +1 -0
- package/dist/types/commands/manifest/setup-manifest-config.d.mts.map +1 -1
- package/dist/types/commands/organization/fetch-organization-list.d.mts +2 -2
- package/dist/types/commands/organization/fetch-organization-list.d.mts.map +1 -1
- package/dist/types/commands/package/output-purls-shallow-score.d.mts.map +1 -1
- package/dist/types/commands/repository/fetch-create-repo.d.mts +2 -2
- package/dist/types/commands/repository/fetch-create-repo.d.mts.map +1 -1
- package/dist/types/commands/repository/fetch-delete-repo.d.mts +2 -2
- package/dist/types/commands/repository/fetch-delete-repo.d.mts.map +1 -1
- package/dist/types/commands/repository/fetch-list-all-repos.d.mts +2 -2
- package/dist/types/commands/repository/fetch-list-all-repos.d.mts.map +1 -1
- package/dist/types/commands/repository/fetch-list-repos.d.mts +2 -2
- package/dist/types/commands/repository/fetch-list-repos.d.mts.map +1 -1
- package/dist/types/commands/repository/fetch-update-repo.d.mts +2 -2
- package/dist/types/commands/repository/fetch-update-repo.d.mts.map +1 -1
- package/dist/types/commands/repository/fetch-view-repo.d.mts +2 -2
- package/dist/types/commands/repository/fetch-view-repo.d.mts.map +1 -1
- package/dist/types/commands/repository/handle-list-repos.d.mts.map +1 -1
- package/dist/types/commands/repository/output-create-repo.d.mts +2 -2
- package/dist/types/commands/repository/output-create-repo.d.mts.map +1 -1
- package/dist/types/commands/repository/output-delete-repo.d.mts +2 -2
- package/dist/types/commands/repository/output-delete-repo.d.mts.map +1 -1
- package/dist/types/commands/repository/output-list-repos.d.mts +2 -2
- package/dist/types/commands/repository/output-list-repos.d.mts.map +1 -1
- package/dist/types/commands/repository/output-update-repo.d.mts +2 -2
- package/dist/types/commands/repository/output-update-repo.d.mts.map +1 -1
- package/dist/types/commands/repository/output-view-repo.d.mts +2 -2
- package/dist/types/commands/repository/output-view-repo.d.mts.map +1 -1
- package/dist/types/commands/scan/cmd-scan-create.d.mts.map +1 -1
- package/dist/types/commands/scan/cmd-scan-reach.d.mts.map +1 -1
- package/dist/types/commands/scan/create-scan-from-github.d.mts.map +1 -1
- package/dist/types/commands/scan/exclude-paths.d.mts +2 -2
- package/dist/types/commands/scan/exclude-paths.d.mts.map +1 -1
- package/dist/types/commands/scan/fetch-create-org-full-scan.d.mts +2 -2
- package/dist/types/commands/scan/fetch-create-org-full-scan.d.mts.map +1 -1
- package/dist/types/commands/scan/fetch-delete-org-full-scan.d.mts +2 -2
- package/dist/types/commands/scan/fetch-delete-org-full-scan.d.mts.map +1 -1
- package/dist/types/commands/scan/fetch-list-scans.d.mts +2 -2
- package/dist/types/commands/scan/fetch-list-scans.d.mts.map +1 -1
- package/dist/types/commands/scan/fetch-scan-metadata.d.mts +2 -2
- package/dist/types/commands/scan/fetch-scan-metadata.d.mts.map +1 -1
- package/dist/types/commands/scan/fetch-scan.d.mts +4 -0
- package/dist/types/commands/scan/fetch-scan.d.mts.map +1 -1
- package/dist/types/commands/scan/fetch-supported-scan-file-names.d.mts +2 -1
- package/dist/types/commands/scan/fetch-supported-scan-file-names.d.mts.map +1 -1
- package/dist/types/commands/scan/finalize-tier1-scan.d.mts +9 -5
- package/dist/types/commands/scan/finalize-tier1-scan.d.mts.map +1 -1
- package/dist/types/commands/scan/handle-create-new-scan.d.mts.map +1 -1
- package/dist/types/commands/scan/handle-scan-reach.d.mts.map +1 -1
- package/dist/types/commands/scan/output-create-new-scan.d.mts +2 -2
- package/dist/types/commands/scan/output-create-new-scan.d.mts.map +1 -1
- package/dist/types/commands/scan/output-delete-scan.d.mts +2 -2
- package/dist/types/commands/scan/output-delete-scan.d.mts.map +1 -1
- package/dist/types/commands/scan/output-list-scans.d.mts +2 -2
- package/dist/types/commands/scan/output-list-scans.d.mts.map +1 -1
- package/dist/types/commands/scan/output-scan-metadata.d.mts +2 -2
- package/dist/types/commands/scan/output-scan-metadata.d.mts.map +1 -1
- package/dist/types/commands/scan/output-scan-reach.d.mts +2 -1
- package/dist/types/commands/scan/output-scan-reach.d.mts.map +1 -1
- package/dist/types/commands/scan/perform-reachability-analysis.d.mts +10 -3
- package/dist/types/commands/scan/perform-reachability-analysis.d.mts.map +1 -1
- package/dist/types/commands/scan/reachability-flags.d.mts.map +1 -1
- package/dist/types/commands/scan/reachability-units.d.mts +18 -0
- package/dist/types/commands/scan/reachability-units.d.mts.map +1 -0
- package/dist/types/commands/scan/stream-scan.d.mts +3 -1
- package/dist/types/commands/scan/stream-scan.d.mts.map +1 -1
- package/dist/types/constants.d.mts +2 -4
- package/dist/types/constants.d.mts.map +1 -1
- package/dist/types/utils/api.d.mts +53 -7
- package/dist/types/utils/api.d.mts.map +1 -1
- package/dist/types/utils/config.d.mts.map +1 -1
- package/dist/types/utils/dlx.d.mts +4 -3
- package/dist/types/utils/dlx.d.mts.map +1 -1
- package/dist/types/utils/ecosystem.d.mts +8 -1
- package/dist/types/utils/ecosystem.d.mts.map +1 -1
- package/dist/types/utils/fs.d.mts +1 -0
- package/dist/types/utils/fs.d.mts.map +1 -1
- package/dist/types/utils/glob.d.mts +5 -4
- package/dist/types/utils/glob.d.mts.map +1 -1
- package/dist/types/utils/meow-with-subcommands.d.mts.map +1 -1
- package/dist/types/utils/path-resolve.d.mts +1 -1
- package/dist/types/utils/path-resolve.d.mts.map +1 -1
- package/dist/types/utils/sdk.d.mts +6 -0
- package/dist/types/utils/sdk.d.mts.map +1 -1
- package/dist/types/utils/self-update.d.mts +3 -0
- package/dist/types/utils/self-update.d.mts.map +1 -0
- package/dist/types/utils/socket-json.d.mts +17 -0
- package/dist/types/utils/socket-json.d.mts.map +1 -1
- package/dist/types/utils/socket-package-alert.d.mts.map +1 -1
- package/dist/utils.js +614 -283
- package/dist/utils.js.map +1 -1
- package/dist/vendor.js +50578 -27781
- package/external/blessed/lib/tput.js +5 -5
- package/package.json +64 -131
- package/requirements.json +1 -1
- package/shadow-bin/npm +0 -0
- package/shadow-bin/npx +0 -0
- package/shadow-bin/pnpm +0 -0
- package/shadow-bin/yarn +0 -0
- package/dist/socket-facts.init.gradle +0 -353
- package/dist/types/commands/manifest/bazel/bazel-build-parser.d.mts +0 -34
- package/dist/types/commands/manifest/bazel/bazel-build-parser.d.mts.map +0 -1
- package/external/blessed/usr/fonts/AUTHORS +0 -1
- package/external/blessed/usr/fonts/LICENSE +0 -94
- package/external/blessed/usr/fonts/README +0 -340
- package/external/blessed/usr/fonts/ter-u14b.json +0 -17826
- package/external/blessed/usr/fonts/ter-u14n.json +0 -17826
package/dist/utils.js
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
var vendor = require('./vendor.js');
|
|
4
4
|
var logger = require('../external/@socketsecurity/registry/lib/logger');
|
|
5
5
|
var strings = require('../external/@socketsecurity/registry/lib/strings');
|
|
6
|
-
var
|
|
7
|
-
var
|
|
6
|
+
var debug$2 = require('../external/@socketsecurity/registry/lib/debug');
|
|
7
|
+
var objects = require('../external/@socketsecurity/registry/lib/objects');
|
|
8
8
|
var constants = require('./constants.js');
|
|
9
9
|
var arrays = require('../external/@socketsecurity/registry/lib/arrays');
|
|
10
10
|
var path$1 = require('../external/@socketsecurity/registry/lib/path');
|
|
@@ -18,22 +18,23 @@ var prompts = require('../external/@socketsecurity/registry/lib/prompts');
|
|
|
18
18
|
var spawn = require('../external/@socketsecurity/registry/lib/spawn');
|
|
19
19
|
var fs = require('node:fs');
|
|
20
20
|
var fs$2 = require('node:fs/promises');
|
|
21
|
-
var
|
|
22
|
-
var
|
|
21
|
+
var require$$9 = require('node:stream/promises');
|
|
22
|
+
var require$$11 = require('node:zlib');
|
|
23
23
|
var fs$1 = require('../external/@socketsecurity/registry/lib/fs');
|
|
24
|
-
var require$$
|
|
24
|
+
var require$$1 = require('node:module');
|
|
25
25
|
var os = require('node:os');
|
|
26
|
-
var require$$
|
|
26
|
+
var require$$13 = require('node:https');
|
|
27
27
|
var web = require('node:stream/web');
|
|
28
|
-
var
|
|
28
|
+
var url = require('../external/@socketsecurity/registry/lib/url');
|
|
29
29
|
var agent = require('../external/@socketsecurity/registry/lib/agent');
|
|
30
30
|
var bin = require('../external/@socketsecurity/registry/lib/bin');
|
|
31
31
|
var packages = require('../external/@socketsecurity/registry/lib/packages');
|
|
32
32
|
var require$$0$1 = require('node:url');
|
|
33
33
|
var globs = require('../external/@socketsecurity/registry/lib/globs');
|
|
34
34
|
var streams = require('../external/@socketsecurity/registry/lib/streams');
|
|
35
|
-
var
|
|
36
|
-
var require$$
|
|
35
|
+
var require$$7 = require('node:timers/promises');
|
|
36
|
+
var require$$10 = require('node:util');
|
|
37
|
+
var require$$12 = require('node:http');
|
|
37
38
|
var node_tls = require('node:tls');
|
|
38
39
|
var process$1 = require('node:process');
|
|
39
40
|
var require$$0 = require('node:crypto');
|
|
@@ -98,13 +99,13 @@ function debugApiResponse(method, endpoint, status, error, duration, headers) {
|
|
|
98
99
|
*/
|
|
99
100
|
function debugFileOp(operation, filepath, error) {
|
|
100
101
|
if (error) {
|
|
101
|
-
|
|
102
|
+
debug$2.debugDir('warn', {
|
|
102
103
|
operation,
|
|
103
104
|
filepath,
|
|
104
105
|
error: error instanceof Error ? error.message : 'Unknown error'
|
|
105
106
|
});
|
|
106
|
-
} else if (
|
|
107
|
-
|
|
107
|
+
} else if (debug$2.isDebug('silly')) {
|
|
108
|
+
debug$2.debugFn('silly', `File ${operation}: ${filepath}`);
|
|
108
109
|
}
|
|
109
110
|
}
|
|
110
111
|
|
|
@@ -116,19 +117,19 @@ function debugScan(phase, packageCount, details) {
|
|
|
116
117
|
switch (phase) {
|
|
117
118
|
case 'start':
|
|
118
119
|
if (packageCount) {
|
|
119
|
-
|
|
120
|
+
debug$2.debugFn('notice', `Scanning ${packageCount} packages`);
|
|
120
121
|
}
|
|
121
122
|
break;
|
|
122
123
|
case 'progress':
|
|
123
|
-
if (
|
|
124
|
-
|
|
124
|
+
if (debug$2.isDebug('silly') && packageCount) {
|
|
125
|
+
debug$2.debugFn('silly', `Scan progress: ${packageCount} packages processed`);
|
|
125
126
|
}
|
|
126
127
|
break;
|
|
127
128
|
case 'complete':
|
|
128
|
-
|
|
129
|
+
debug$2.debugFn('notice', `Scan complete${packageCount ? `: ${packageCount} packages` : ''}`);
|
|
129
130
|
break;
|
|
130
131
|
case 'error':
|
|
131
|
-
|
|
132
|
+
debug$2.debugDir('error', {
|
|
132
133
|
phase: 'scan_error',
|
|
133
134
|
details
|
|
134
135
|
});
|
|
@@ -141,14 +142,14 @@ function debugScan(phase, packageCount, details) {
|
|
|
141
142
|
*/
|
|
142
143
|
function debugConfig(source, found, error) {
|
|
143
144
|
if (error) {
|
|
144
|
-
|
|
145
|
+
debug$2.debugDir('warn', {
|
|
145
146
|
source,
|
|
146
147
|
error: error instanceof Error ? error.message : 'Unknown error'
|
|
147
148
|
});
|
|
148
149
|
} else if (found) {
|
|
149
|
-
|
|
150
|
-
} else if (
|
|
151
|
-
|
|
150
|
+
debug$2.debugFn('notice', `Config loaded: ${source}`);
|
|
151
|
+
} else if (debug$2.isDebug('silly')) {
|
|
152
|
+
debug$2.debugFn('silly', `Config not found: ${source}`);
|
|
152
153
|
}
|
|
153
154
|
}
|
|
154
155
|
|
|
@@ -158,15 +159,15 @@ function debugConfig(source, found, error) {
|
|
|
158
159
|
*/
|
|
159
160
|
function debugGit(operation, success, details) {
|
|
160
161
|
if (!success) {
|
|
161
|
-
|
|
162
|
+
debug$2.debugDir('warn', {
|
|
162
163
|
git_op: operation,
|
|
163
164
|
...details
|
|
164
165
|
});
|
|
165
|
-
} else if (
|
|
166
|
+
} else if (debug$2.isDebug('notice') && operation.includes('push') || operation.includes('commit')) {
|
|
166
167
|
// Only log important operations like push and commit.
|
|
167
|
-
|
|
168
|
-
} else if (
|
|
169
|
-
|
|
168
|
+
debug$2.debugFn('notice', `Git ${operation} succeeded`);
|
|
169
|
+
} else if (debug$2.isDebug('silly')) {
|
|
170
|
+
debug$2.debugFn('silly', `Git ${operation}`);
|
|
170
171
|
}
|
|
171
172
|
}
|
|
172
173
|
|
|
@@ -280,7 +281,7 @@ function shouldSave(currentContent, originalContent, originalFileContent, option
|
|
|
280
281
|
const sortedContent = sort ? sortKeys(content) : content;
|
|
281
282
|
const origContent = originalContent ? stripFormattingSymbols(originalContent) : {};
|
|
282
283
|
if (ignoreWhitespace) {
|
|
283
|
-
return !require$$
|
|
284
|
+
return !require$$10.isDeepStrictEqual(sortedContent, origContent);
|
|
284
285
|
}
|
|
285
286
|
const formatting = getFormattingFromContent(currentContent);
|
|
286
287
|
const newFileContent = stringifyWithFormatting(sortedContent, formatting);
|
|
@@ -297,7 +298,7 @@ async function retryWrite(filepath, content, retries = 3, baseDelay = 10) {
|
|
|
297
298
|
await fs.promises.writeFile(filepath, content);
|
|
298
299
|
if (process.platform === 'win32') {
|
|
299
300
|
// eslint-disable-next-line no-await-in-loop
|
|
300
|
-
await
|
|
301
|
+
await require$$7.setTimeout(50);
|
|
301
302
|
let accessRetries = 0;
|
|
302
303
|
const maxAccessRetries = 5;
|
|
303
304
|
while (accessRetries < maxAccessRetries) {
|
|
@@ -305,12 +306,12 @@ async function retryWrite(filepath, content, retries = 3, baseDelay = 10) {
|
|
|
305
306
|
// eslint-disable-next-line no-await-in-loop
|
|
306
307
|
await fs.promises.access(filepath);
|
|
307
308
|
// eslint-disable-next-line no-await-in-loop
|
|
308
|
-
await
|
|
309
|
+
await require$$7.setTimeout(10);
|
|
309
310
|
break;
|
|
310
311
|
} catch {
|
|
311
312
|
const delay = 20 * (accessRetries + 1);
|
|
312
313
|
// eslint-disable-next-line no-await-in-loop
|
|
313
|
-
await
|
|
314
|
+
await require$$7.setTimeout(delay);
|
|
314
315
|
accessRetries++;
|
|
315
316
|
}
|
|
316
317
|
}
|
|
@@ -324,7 +325,7 @@ async function retryWrite(filepath, content, retries = 3, baseDelay = 10) {
|
|
|
324
325
|
}
|
|
325
326
|
const delay = baseDelay * 2 ** attempt;
|
|
326
327
|
// eslint-disable-next-line no-await-in-loop
|
|
327
|
-
await
|
|
328
|
+
await require$$7.setTimeout(delay);
|
|
328
329
|
}
|
|
329
330
|
}
|
|
330
331
|
}
|
|
@@ -353,7 +354,7 @@ async function readFile(filepath) {
|
|
|
353
354
|
}
|
|
354
355
|
const delay = process.platform === 'win32' ? 50 * (attempt + 1) : 20;
|
|
355
356
|
// eslint-disable-next-line no-await-in-loop
|
|
356
|
-
await
|
|
357
|
+
await require$$7.setTimeout(delay);
|
|
357
358
|
}
|
|
358
359
|
}
|
|
359
360
|
throw new Error('Unreachable code');
|
|
@@ -410,7 +411,7 @@ class EditableJson {
|
|
|
410
411
|
const indent = detectIndent(data);
|
|
411
412
|
const newline = detectNewline(data)
|
|
412
413
|
// Use type assertion to allow symbol indexing.
|
|
413
|
-
|
|
414
|
+
;
|
|
414
415
|
parsed[INDENT_SYMBOL] = indent;
|
|
415
416
|
parsed[NEWLINE_SYMBOL] = newline;
|
|
416
417
|
this._content = parsed;
|
|
@@ -524,7 +525,7 @@ class InputError extends Error {
|
|
|
524
525
|
async function captureException(exception, hint) {
|
|
525
526
|
const result = captureExceptionSync(exception, hint);
|
|
526
527
|
// "Sleep" for a second, just in case, hopefully enough time to initiate fetch.
|
|
527
|
-
await
|
|
528
|
+
await require$$7.setTimeout(1000);
|
|
528
529
|
return result;
|
|
529
530
|
}
|
|
530
531
|
function captureExceptionSync(exception, hint) {
|
|
@@ -532,7 +533,7 @@ function captureExceptionSync(exception, hint) {
|
|
|
532
533
|
if (!Sentry) {
|
|
533
534
|
return '';
|
|
534
535
|
}
|
|
535
|
-
|
|
536
|
+
debug$2.debugFn('notice', 'send: exception to Sentry');
|
|
536
537
|
return Sentry.captureException(exception, hint);
|
|
537
538
|
}
|
|
538
539
|
|
|
@@ -694,8 +695,8 @@ function findSocketYmlSync(dir = process.cwd()) {
|
|
|
694
695
|
}
|
|
695
696
|
};
|
|
696
697
|
} catch (e) {
|
|
697
|
-
|
|
698
|
-
|
|
698
|
+
debug$2.debugFn('error', `Failed to parse config file: ${ymlPath}`);
|
|
699
|
+
debug$2.debugDir('error', e);
|
|
699
700
|
return {
|
|
700
701
|
ok: false,
|
|
701
702
|
message: `Found file but was unable to parse ${ymlPath}`,
|
|
@@ -759,7 +760,7 @@ let _cachedConfig;
|
|
|
759
760
|
// When using --config or SOCKET_CLI_CONFIG, do not persist the config.
|
|
760
761
|
let _configFromFlag = false;
|
|
761
762
|
function overrideCachedConfig(jsonConfig) {
|
|
762
|
-
|
|
763
|
+
debug$2.debugFn('notice', 'override: full config (not stored)');
|
|
763
764
|
let config;
|
|
764
765
|
try {
|
|
765
766
|
config = JSON.parse(String(jsonConfig));
|
|
@@ -801,15 +802,22 @@ function overrideCachedConfig(jsonConfig) {
|
|
|
801
802
|
};
|
|
802
803
|
}
|
|
803
804
|
function overrideConfigApiToken(apiToken) {
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
|
|
805
|
+
debug$2.debugFn('notice', 'override: Socket API token (not stored)');
|
|
806
|
+
if (apiToken === undefined) {
|
|
807
|
+
// SOCKET_CLI_NO_API_TOKEN: operate with no token and lock the config to
|
|
808
|
+
// read-only so nothing is persisted for this run.
|
|
809
|
+
_cachedConfig = {
|
|
810
|
+
...vendor.configExports
|
|
811
|
+
};
|
|
812
|
+
_configFromFlag = true;
|
|
813
|
+
return;
|
|
814
|
+
}
|
|
815
|
+
// A token supplied via env (SOCKET_CLI_API_TOKEN / SOCKET_SECURITY_API_TOKEN)
|
|
816
|
+
// overrides authentication only. getDefaultApiToken() reads it straight from
|
|
817
|
+
// the environment, so we intentionally do NOT inject it into the cached config
|
|
818
|
+
// and do NOT mark the config read-only: unrelated keys (e.g. defaultOrg) can
|
|
819
|
+
// still be saved with `socket config set`, while the env token never reaches
|
|
820
|
+
// disk because it never enters the persisted cache.
|
|
813
821
|
}
|
|
814
822
|
let _pendingSave = false;
|
|
815
823
|
function updateConfigValue(configKey, value) {
|
|
@@ -838,7 +846,7 @@ function updateConfigValue(configKey, value) {
|
|
|
838
846
|
return {
|
|
839
847
|
ok: true,
|
|
840
848
|
message: `Config key '${key}' was ${wasDeleted ? 'deleted' : `updated`}`,
|
|
841
|
-
data: '
|
|
849
|
+
data: 'The active config is read-only because it was fully overridden by the ' + '--config flag, SOCKET_CLI_CONFIG, or SOCKET_CLI_NO_API_TOKEN. Remove ' + 'the override to save changes to disk.'
|
|
842
850
|
};
|
|
843
851
|
}
|
|
844
852
|
if (!_pendingSave) {
|
|
@@ -931,7 +939,7 @@ function updateConfigValue(configKey, value) {
|
|
|
931
939
|
* - Used for permission validation and help text
|
|
932
940
|
*/
|
|
933
941
|
|
|
934
|
-
const require$3 = require$$
|
|
942
|
+
const require$3 = require$$1.createRequire((typeof document === 'undefined' ? require$$0$1.pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('utils.js', document.baseURI).href)));
|
|
935
943
|
let _requirements;
|
|
936
944
|
function getRequirements() {
|
|
937
945
|
if (_requirements === undefined) {
|
|
@@ -995,14 +1003,14 @@ function getRequirementsKey(cmdPath) {
|
|
|
995
1003
|
* Wraps debugFn to provide a simpler API.
|
|
996
1004
|
*/
|
|
997
1005
|
const debug$1 = message => {
|
|
998
|
-
|
|
1006
|
+
debug$2.debugFn('socket:telemetry:service', message);
|
|
999
1007
|
};
|
|
1000
1008
|
|
|
1001
1009
|
/**
|
|
1002
1010
|
* DebugDir wrapper for telemetry service.
|
|
1003
1011
|
*/
|
|
1004
1012
|
const debugDirWrapper = obj => {
|
|
1005
|
-
|
|
1013
|
+
debug$2.debugDir('socket:telemetry:service', obj);
|
|
1006
1014
|
};
|
|
1007
1015
|
|
|
1008
1016
|
/**
|
|
@@ -1367,7 +1375,7 @@ class TelemetryService {
|
|
|
1367
1375
|
* Debug wrapper for telemetry integration.
|
|
1368
1376
|
*/
|
|
1369
1377
|
const debug = message => {
|
|
1370
|
-
|
|
1378
|
+
debug$2.debugFn('socket:telemetry:integration', message);
|
|
1371
1379
|
};
|
|
1372
1380
|
|
|
1373
1381
|
/**
|
|
@@ -1816,6 +1824,32 @@ async function trackSubprocessError(command, startTime, error, exitCode, metadat
|
|
|
1816
1824
|
* - Includes CLI version and platform information
|
|
1817
1825
|
*/
|
|
1818
1826
|
|
|
1827
|
+
// SDK v4 rejects request timeouts outside this range (see the SDK's
|
|
1828
|
+
// MIN_HTTP_TIMEOUT / MAX_HTTP_TIMEOUT). The SDK does not re-export those
|
|
1829
|
+
// constants, so the bounds are mirrored here.
|
|
1830
|
+
const MIN_API_TIMEOUT_MS = 5_000;
|
|
1831
|
+
const MAX_API_TIMEOUT_MS = 300_000;
|
|
1832
|
+
|
|
1833
|
+
// Clamp a SOCKET_CLI_API_TIMEOUT value into the SDK's accepted range. The SDK
|
|
1834
|
+
// throws a TypeError on out-of-range timeouts, so an out-of-range user value
|
|
1835
|
+
// would otherwise make every API call fail; clamping preserves intent (a small
|
|
1836
|
+
// value maps to the floor, a huge value to the ceiling) while staying valid.
|
|
1837
|
+
function clampApiTimeout(timeout) {
|
|
1838
|
+
return Math.min(Math.max(timeout, MIN_API_TIMEOUT_MS), MAX_API_TIMEOUT_MS);
|
|
1839
|
+
}
|
|
1840
|
+
|
|
1841
|
+
// Lazy-evaluated full CLI user agent for direct (non-SDK) API calls.
|
|
1842
|
+
// Includes the CLI product token, Node.js version, and OS platform/arch.
|
|
1843
|
+
// e.g. "socket/1.1.96 node/v22.0.0 linux/arm64"
|
|
1844
|
+
let _cliUserAgent;
|
|
1845
|
+
function getCliUserAgent() {
|
|
1846
|
+
if (!_cliUserAgent) {
|
|
1847
|
+
const name = constants.default.ENV.INLINED_SOCKET_CLI_NAME.replace('@', '').replace('/', '-');
|
|
1848
|
+
const version = constants.default.ENV.INLINED_SOCKET_CLI_VERSION;
|
|
1849
|
+
_cliUserAgent = [`${name}/${version}`, `node/${process.version}`, `${process.platform}/${process.arch}`].join(' ');
|
|
1850
|
+
}
|
|
1851
|
+
return _cliUserAgent;
|
|
1852
|
+
}
|
|
1819
1853
|
const TOKEN_PREFIX = 'sktsec_';
|
|
1820
1854
|
const TOKEN_PREFIX_LENGTH = TOKEN_PREFIX.length;
|
|
1821
1855
|
const TOKEN_VISIBLE_LENGTH = 5;
|
|
@@ -1823,13 +1857,13 @@ const TOKEN_VISIBLE_LENGTH = 5;
|
|
|
1823
1857
|
// The Socket API server that should be used for operations.
|
|
1824
1858
|
function getDefaultApiBaseUrl$1() {
|
|
1825
1859
|
const baseUrl = constants.default.ENV.SOCKET_CLI_API_BASE_URL || getConfigValueOrUndef(constants.CONFIG_KEY_API_BASE_URL);
|
|
1826
|
-
return
|
|
1860
|
+
return url.isUrl(baseUrl) ? baseUrl : undefined;
|
|
1827
1861
|
}
|
|
1828
1862
|
|
|
1829
1863
|
// The Socket API server that should be used for operations.
|
|
1830
1864
|
function getDefaultProxyUrl() {
|
|
1831
1865
|
const apiProxy = constants.default.ENV.SOCKET_CLI_API_PROXY || getConfigValueOrUndef(constants.CONFIG_KEY_API_PROXY);
|
|
1832
|
-
return
|
|
1866
|
+
return url.isUrl(apiProxy) ? apiProxy : undefined;
|
|
1833
1867
|
}
|
|
1834
1868
|
|
|
1835
1869
|
// Cached extra CA certificates for SSL_CERT_FILE support.
|
|
@@ -1862,7 +1896,7 @@ function getExtraCaCerts() {
|
|
|
1862
1896
|
_extraCaCerts = [...node_tls.rootCertificates, extraCerts];
|
|
1863
1897
|
return _extraCaCerts;
|
|
1864
1898
|
} catch (e) {
|
|
1865
|
-
|
|
1899
|
+
debug$2.debugFn('warn', `Failed to read certificate file: ${certPath}`, e);
|
|
1866
1900
|
return undefined;
|
|
1867
1901
|
}
|
|
1868
1902
|
}
|
|
@@ -1912,7 +1946,7 @@ async function setupSdk(options) {
|
|
|
1912
1946
|
let {
|
|
1913
1947
|
apiProxy
|
|
1914
1948
|
} = opts;
|
|
1915
|
-
if (!
|
|
1949
|
+
if (!url.isUrl(apiProxy)) {
|
|
1916
1950
|
apiProxy = getDefaultProxyUrl();
|
|
1917
1951
|
}
|
|
1918
1952
|
const {
|
|
@@ -1921,31 +1955,45 @@ async function setupSdk(options) {
|
|
|
1921
1955
|
|
|
1922
1956
|
// Usage of HttpProxyAgent vs. HttpsProxyAgent based on the chart at:
|
|
1923
1957
|
// https://github.com/delvedor/hpagent?tab=readme-ov-file#usage
|
|
1924
|
-
const
|
|
1958
|
+
const isHttp = apiBaseUrl?.startsWith('http:');
|
|
1959
|
+
const ProxyAgent = isHttp ? vendor.HttpProxyAgent : vendor.HttpsProxyAgent;
|
|
1925
1960
|
|
|
1926
1961
|
// Load extra CA certificates for SSL_CERT_FILE support when
|
|
1927
1962
|
// NODE_EXTRA_CA_CERTS was not set at process startup.
|
|
1928
1963
|
const ca = getExtraCaCerts();
|
|
1964
|
+
|
|
1965
|
+
// Always pass an explicit agent. Node >=19's global agent enables keepAlive
|
|
1966
|
+
// with a 5s socket timeout that Node applies as a per-socket inactivity
|
|
1967
|
+
// timeout. A request made without an explicit agent inherits it and is torn
|
|
1968
|
+
// down after 5s of socket inactivity, even when SOCKET_CLI_API_TIMEOUT is
|
|
1969
|
+
// unset. This breaks slow endpoints like upload-manifest-files, which streams
|
|
1970
|
+
// a chunked multipart body while the server parses auth/multipart before
|
|
1971
|
+
// sending any response byte. A fresh Agent carries no timeout, so a request
|
|
1972
|
+
// is bounded only by a real SOCKET_CLI_API_TIMEOUT (applied below via the
|
|
1973
|
+
// SDK's timeout option) or until interrupted.
|
|
1929
1974
|
const sdkOptions = {
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
} :
|
|
1941
|
-
agent: new require$$3.Agent({
|
|
1942
|
-
ca
|
|
1943
|
-
})
|
|
1944
|
-
} : {}),
|
|
1975
|
+
agent: apiProxy ? new ProxyAgent({
|
|
1976
|
+
proxy: apiProxy,
|
|
1977
|
+
...(ca ? {
|
|
1978
|
+
ca,
|
|
1979
|
+
proxyConnectOptions: {
|
|
1980
|
+
ca
|
|
1981
|
+
}
|
|
1982
|
+
} : {})
|
|
1983
|
+
}) : isHttp ? new require$$12.Agent() : new require$$13.Agent(ca ? {
|
|
1984
|
+
ca
|
|
1985
|
+
} : undefined),
|
|
1945
1986
|
...(apiBaseUrl ? {
|
|
1946
1987
|
baseUrl: apiBaseUrl
|
|
1947
1988
|
} : {}),
|
|
1948
|
-
timeout
|
|
1989
|
+
// SDK v4 validates the request timeout to be within [5000, 300000] ms and
|
|
1990
|
+
// throws otherwise. Only forward a truthy timeout; when unset (0) omit it
|
|
1991
|
+
// so the SDK applies its own default instead of rejecting the value. A
|
|
1992
|
+
// truthy-but-out-of-range value is clamped into the accepted range rather
|
|
1993
|
+
// than forwarded, which would make every SDK call throw.
|
|
1994
|
+
...(constants.default.ENV.SOCKET_CLI_API_TIMEOUT ? {
|
|
1995
|
+
timeout: clampApiTimeout(constants.default.ENV.SOCKET_CLI_API_TIMEOUT)
|
|
1996
|
+
} : {}),
|
|
1949
1997
|
userAgent: vendor.distExports.createUserAgentFromPkgJson({
|
|
1950
1998
|
name: constants.default.ENV.INLINED_SOCKET_CLI_NAME,
|
|
1951
1999
|
version: constants.default.ENV.INLINED_SOCKET_CLI_VERSION,
|
|
@@ -2034,32 +2082,36 @@ async function setupSdk(options) {
|
|
|
2034
2082
|
const MAX_REDIRECTS = 20;
|
|
2035
2083
|
const NO_ERROR_MESSAGE = 'No error message returned';
|
|
2036
2084
|
|
|
2037
|
-
// Cached HTTPS agent for
|
|
2085
|
+
// Cached HTTPS agent for direct API calls. Undefined only until the first
|
|
2086
|
+
// getHttpsAgent() call lazily creates it.
|
|
2038
2087
|
let _httpsAgent;
|
|
2039
|
-
let _httpsAgentResolved = false;
|
|
2040
2088
|
|
|
2041
|
-
// Returns an HTTPS agent
|
|
2042
|
-
// SSL_CERT_FILE is set but NODE_EXTRA_CA_CERTS is not.
|
|
2089
|
+
// Returns an explicit HTTPS agent for direct API calls, carrying extra CA
|
|
2090
|
+
// certificates when SSL_CERT_FILE is set but NODE_EXTRA_CA_CERTS is not. An
|
|
2091
|
+
// explicit agent is always returned. Node >=19's global agent enables keepAlive
|
|
2092
|
+
// with a 5s socket timeout that Node applies as a per-socket inactivity
|
|
2093
|
+
// timeout. A request made without an explicit agent inherits it and is torn
|
|
2094
|
+
// down after 5s of socket inactivity, prematurely dropping slow or idle-gapped
|
|
2095
|
+
// requests (e.g. streaming full-scan responses, large downloads) even when no
|
|
2096
|
+
// timeout was requested. A fresh Agent carries no timeout.
|
|
2043
2097
|
function getHttpsAgent() {
|
|
2044
|
-
if (
|
|
2098
|
+
if (_httpsAgent) {
|
|
2045
2099
|
return _httpsAgent;
|
|
2046
2100
|
}
|
|
2047
|
-
_httpsAgentResolved = true;
|
|
2048
2101
|
const ca = getExtraCaCerts();
|
|
2049
|
-
|
|
2050
|
-
return undefined;
|
|
2051
|
-
}
|
|
2052
|
-
_httpsAgent = new require$$3.Agent({
|
|
2102
|
+
const agent = ca ? new require$$13.Agent({
|
|
2053
2103
|
ca
|
|
2054
|
-
});
|
|
2055
|
-
|
|
2104
|
+
}) : new require$$13.Agent();
|
|
2105
|
+
_httpsAgent = agent;
|
|
2106
|
+
return agent;
|
|
2056
2107
|
}
|
|
2057
2108
|
|
|
2058
2109
|
// All outbound API requests use node:https.request rather than global fetch.
|
|
2059
2110
|
// This ensures no body timeout is applied ā large streaming ND-JSON responses
|
|
2060
|
-
// (e.g. full scan results) can transfer without a hard deadline.
|
|
2061
|
-
//
|
|
2062
|
-
//
|
|
2111
|
+
// (e.g. full scan results) can transfer without a hard deadline. An explicit
|
|
2112
|
+
// HttpsAgent is always passed (carrying extra CA certificates when
|
|
2113
|
+
// SSL_CERT_FILE is configured) so requests do not inherit Node's global-agent
|
|
2114
|
+
// keepAlive socket timeout.
|
|
2063
2115
|
|
|
2064
2116
|
// Internal httpsRequest-based fetch with redirect support.
|
|
2065
2117
|
function _httpsRequestFetch(url, init, agent, redirectCount) {
|
|
@@ -2071,7 +2123,7 @@ function _httpsRequestFetch(url, init, agent, redirectCount) {
|
|
|
2071
2123
|
if (init.body) {
|
|
2072
2124
|
headers['content-length'] = String(Buffer.byteLength(init.body));
|
|
2073
2125
|
}
|
|
2074
|
-
const req = require$$
|
|
2126
|
+
const req = require$$13.request(url, {
|
|
2075
2127
|
method: init.method || 'GET',
|
|
2076
2128
|
headers,
|
|
2077
2129
|
agent
|
|
@@ -2220,6 +2272,26 @@ async function getErrorMessageForHttpStatusCode(code) {
|
|
|
2220
2272
|
}
|
|
2221
2273
|
return `Server responded with status code ${code}`;
|
|
2222
2274
|
}
|
|
2275
|
+
|
|
2276
|
+
/**
|
|
2277
|
+
* The subset of a Socket SDK result that {@link handleApiCall} reads. Both the
|
|
2278
|
+
* OpenAPI-derived `SocketSdkResult<T>` family and the SDK 4.x strict result
|
|
2279
|
+
* types (`OrganizationsResult`, `RepositoryResult`, `DeleteResult`, ...)
|
|
2280
|
+
* structurally satisfy this shape, so a caller can pass whichever result a
|
|
2281
|
+
* given SDK method returns without forcing a (sometimes stale) operation-key
|
|
2282
|
+
* shape onto the strict return types.
|
|
2283
|
+
*/
|
|
2284
|
+
|
|
2285
|
+
/**
|
|
2286
|
+
* The success `data` type carried by a Socket SDK result union `R`. The
|
|
2287
|
+
* conditional distributes over `R`'s members, so only the success member(s)
|
|
2288
|
+
* contribute their `data`; the error member resolves to `never` and drops out.
|
|
2289
|
+
* Inferring the whole result `R` and extracting here (rather than inferring a
|
|
2290
|
+
* bare `Data` from a `Promise<{ data: Data } | ...>`) avoids `Data` absorbing
|
|
2291
|
+
* the error branch's `data?: undefined` ā which would otherwise widen every
|
|
2292
|
+
* result to `CResult<Data | undefined>`.
|
|
2293
|
+
*/
|
|
2294
|
+
|
|
2223
2295
|
/**
|
|
2224
2296
|
* Handle Socket SDK API calls with error handling and permission logging.
|
|
2225
2297
|
*/
|
|
@@ -2268,25 +2340,25 @@ async function handleApiCall(value, options) {
|
|
|
2268
2340
|
if (description && !silence) {
|
|
2269
2341
|
logger.logger.fail(`An error was thrown while requesting ${description}`);
|
|
2270
2342
|
}
|
|
2271
|
-
|
|
2343
|
+
debug$2.debugDir('inspect', {
|
|
2272
2344
|
socketSdkErrorResult
|
|
2273
2345
|
});
|
|
2274
2346
|
return socketSdkErrorResult;
|
|
2275
2347
|
}
|
|
2276
2348
|
|
|
2277
|
-
//
|
|
2349
|
+
// The `success` discriminant is a concrete boolean literal in both branches,
|
|
2350
|
+
// so this narrows the result to its error branch regardless of `R`.
|
|
2278
2351
|
if (sdkResult.success === false) {
|
|
2279
2352
|
const endpoint = description || 'Socket API';
|
|
2280
2353
|
debugApiResponse('API', endpoint, sdkResult.status);
|
|
2281
|
-
|
|
2354
|
+
debug$2.debugDir('inspect', {
|
|
2282
2355
|
sdkResult
|
|
2283
2356
|
});
|
|
2284
|
-
const
|
|
2285
|
-
const errStr = errCResult.error ? String(errCResult.error).trim() : '';
|
|
2357
|
+
const errStr = sdkResult.error ? String(sdkResult.error).trim() : '';
|
|
2286
2358
|
const message = errStr || NO_ERROR_MESSAGE;
|
|
2287
|
-
const reason =
|
|
2359
|
+
const reason = sdkResult.cause || NO_ERROR_MESSAGE;
|
|
2288
2360
|
const baseCause = reason && message !== reason ? `${message} (reason: ${reason})` : message;
|
|
2289
|
-
const cause =
|
|
2361
|
+
const cause = sdkResult.url ? `${baseCause} (url: ${sdkResult.url})` : baseCause;
|
|
2290
2362
|
const socketSdkErrorResult = {
|
|
2291
2363
|
ok: false,
|
|
2292
2364
|
message: 'Socket API error',
|
|
@@ -2302,6 +2374,9 @@ async function handleApiCall(value, options) {
|
|
|
2302
2374
|
}
|
|
2303
2375
|
return socketSdkErrorResult;
|
|
2304
2376
|
}
|
|
2377
|
+
// Narrowing a type parameter by its `success` discriminant resolves `.data`
|
|
2378
|
+
// through the constraint's success branch (`unknown`); re-apply the precise
|
|
2379
|
+
// per-call success type the return contract already guarantees.
|
|
2305
2380
|
const socketSdkSuccessResult = {
|
|
2306
2381
|
ok: true,
|
|
2307
2382
|
data: sdkResult.data
|
|
@@ -2313,8 +2388,8 @@ async function handleApiCallNoSpinner(value, description) {
|
|
|
2313
2388
|
try {
|
|
2314
2389
|
sdkResult = await value;
|
|
2315
2390
|
} catch (e) {
|
|
2316
|
-
|
|
2317
|
-
|
|
2391
|
+
debug$2.debugFn('error', `API request failed: ${description}`);
|
|
2392
|
+
debug$2.debugDir('error', e);
|
|
2318
2393
|
const errStr = e ? String(e).trim() : '';
|
|
2319
2394
|
const message = 'Socket API error';
|
|
2320
2395
|
const rawCause = errStr || NO_ERROR_MESSAGE;
|
|
@@ -2328,18 +2403,18 @@ async function handleApiCallNoSpinner(value, description) {
|
|
|
2328
2403
|
};
|
|
2329
2404
|
}
|
|
2330
2405
|
|
|
2331
|
-
//
|
|
2406
|
+
// The `success` discriminant is a concrete boolean literal in both branches,
|
|
2407
|
+
// so this narrows the result to its error branch regardless of `R`.
|
|
2332
2408
|
if (sdkResult.success === false) {
|
|
2333
|
-
|
|
2334
|
-
|
|
2409
|
+
debug$2.debugFn('error', `fail: ${description} bad response`);
|
|
2410
|
+
debug$2.debugDir('inspect', {
|
|
2335
2411
|
sdkResult
|
|
2336
2412
|
});
|
|
2337
|
-
const
|
|
2338
|
-
const errStr = sdkErrorResult.error ? String(sdkErrorResult.error).trim() : '';
|
|
2413
|
+
const errStr = sdkResult.error ? String(sdkResult.error).trim() : '';
|
|
2339
2414
|
const message = errStr || NO_ERROR_MESSAGE;
|
|
2340
|
-
const reason =
|
|
2415
|
+
const reason = sdkResult.cause || NO_ERROR_MESSAGE;
|
|
2341
2416
|
const baseCause = reason && message !== reason ? `${message} (reason: ${reason})` : message;
|
|
2342
|
-
const cause =
|
|
2417
|
+
const cause = sdkResult.url ? `${baseCause} (url: ${sdkResult.url})` : baseCause;
|
|
2343
2418
|
return {
|
|
2344
2419
|
ok: false,
|
|
2345
2420
|
message: 'Socket API error',
|
|
@@ -2349,10 +2424,12 @@ async function handleApiCallNoSpinner(value, description) {
|
|
|
2349
2424
|
}
|
|
2350
2425
|
};
|
|
2351
2426
|
} else {
|
|
2352
|
-
|
|
2427
|
+
// Narrowing a type parameter by its `success` discriminant resolves `.data`
|
|
2428
|
+
// through the constraint's success branch (`unknown`); re-apply the precise
|
|
2429
|
+
// per-call success type the return contract already guarantees.
|
|
2353
2430
|
return {
|
|
2354
2431
|
ok: true,
|
|
2355
|
-
data:
|
|
2432
|
+
data: sdkResult.data
|
|
2356
2433
|
};
|
|
2357
2434
|
}
|
|
2358
2435
|
}
|
|
@@ -2365,16 +2442,19 @@ async function queryApi(path, apiToken) {
|
|
|
2365
2442
|
const result = await apiFetch(url, {
|
|
2366
2443
|
method: 'GET',
|
|
2367
2444
|
headers: {
|
|
2368
|
-
Authorization: `Basic ${btoa(`${apiToken}:`)}
|
|
2445
|
+
Authorization: `Basic ${btoa(`${apiToken}:`)}`,
|
|
2446
|
+
'User-Agent': getCliUserAgent()
|
|
2369
2447
|
}
|
|
2370
2448
|
});
|
|
2371
2449
|
return result;
|
|
2372
2450
|
}
|
|
2373
|
-
|
|
2374
2451
|
/**
|
|
2375
|
-
* Query Socket API endpoint and return
|
|
2452
|
+
* Query a Socket API endpoint and return the HTTP status alongside the text
|
|
2453
|
+
* body, with error handling. Unlike queryApiSafeText this surfaces the status
|
|
2454
|
+
* on success (including 2xx statuses like 202 Accepted), so callers can drive
|
|
2455
|
+
* status-dependent flows such as the cached-scan 202 poll loop.
|
|
2376
2456
|
*/
|
|
2377
|
-
async function
|
|
2457
|
+
async function queryApiSafeTextWithStatus(path, description, commandPath) {
|
|
2378
2458
|
const apiToken = getDefaultApiToken();
|
|
2379
2459
|
if (!apiToken) {
|
|
2380
2460
|
return {
|
|
@@ -2405,8 +2485,8 @@ async function queryApiSafeText(path, description, commandPath) {
|
|
|
2405
2485
|
spinner.failAndStop(`An error was thrown while requesting ${description}.`);
|
|
2406
2486
|
debugApiResponse('GET', path, undefined, e, duration);
|
|
2407
2487
|
}
|
|
2408
|
-
|
|
2409
|
-
|
|
2488
|
+
debug$2.debugFn('error', 'Query API request failed');
|
|
2489
|
+
debug$2.debugDir('error', e);
|
|
2410
2490
|
const errStr = e ? String(e).trim() : '';
|
|
2411
2491
|
const message = 'API request failed';
|
|
2412
2492
|
const rawCause = errStr || NO_ERROR_MESSAGE;
|
|
@@ -2432,14 +2512,17 @@ async function queryApiSafeText(path, description, commandPath) {
|
|
|
2432
2512
|
};
|
|
2433
2513
|
}
|
|
2434
2514
|
try {
|
|
2435
|
-
const
|
|
2515
|
+
const text = await result.text();
|
|
2436
2516
|
return {
|
|
2437
2517
|
ok: true,
|
|
2438
|
-
data
|
|
2518
|
+
data: {
|
|
2519
|
+
status: result.status,
|
|
2520
|
+
text
|
|
2521
|
+
}
|
|
2439
2522
|
};
|
|
2440
2523
|
} catch (e) {
|
|
2441
|
-
|
|
2442
|
-
|
|
2524
|
+
debug$2.debugFn('error', 'Failed to read API response text');
|
|
2525
|
+
debug$2.debugDir('error', e);
|
|
2443
2526
|
return {
|
|
2444
2527
|
ok: false,
|
|
2445
2528
|
message: 'API request failed',
|
|
@@ -2448,6 +2531,17 @@ async function queryApiSafeText(path, description, commandPath) {
|
|
|
2448
2531
|
}
|
|
2449
2532
|
}
|
|
2450
2533
|
|
|
2534
|
+
/**
|
|
2535
|
+
* Query Socket API endpoint and return text response with error handling.
|
|
2536
|
+
*/
|
|
2537
|
+
async function queryApiSafeText(path, description, commandPath) {
|
|
2538
|
+
const result = await queryApiSafeTextWithStatus(path, description);
|
|
2539
|
+
return result.ok ? {
|
|
2540
|
+
ok: true,
|
|
2541
|
+
data: result.data.text
|
|
2542
|
+
} : result;
|
|
2543
|
+
}
|
|
2544
|
+
|
|
2451
2545
|
/**
|
|
2452
2546
|
* Query Socket API endpoint and return parsed JSON response.
|
|
2453
2547
|
*/
|
|
@@ -2510,7 +2604,8 @@ async function sendApiRequest(path, options) {
|
|
|
2510
2604
|
method,
|
|
2511
2605
|
headers: {
|
|
2512
2606
|
Authorization: `Basic ${btoa(`${apiToken}:`)}`,
|
|
2513
|
-
'Content-Type': 'application/json'
|
|
2607
|
+
'Content-Type': 'application/json',
|
|
2608
|
+
'User-Agent': getCliUserAgent()
|
|
2514
2609
|
},
|
|
2515
2610
|
...(body ? {
|
|
2516
2611
|
body: JSON.stringify(body)
|
|
@@ -2524,8 +2619,8 @@ async function sendApiRequest(path, options) {
|
|
|
2524
2619
|
if (description) {
|
|
2525
2620
|
spinner.failAndStop(`An error was thrown while requesting ${description}.`);
|
|
2526
2621
|
}
|
|
2527
|
-
|
|
2528
|
-
|
|
2622
|
+
debug$2.debugFn('error', `API ${method} request failed`);
|
|
2623
|
+
debug$2.debugDir('error', e);
|
|
2529
2624
|
const errStr = e ? String(e).trim() : '';
|
|
2530
2625
|
const message = 'API request failed';
|
|
2531
2626
|
const rawCause = errStr || NO_ERROR_MESSAGE;
|
|
@@ -2561,8 +2656,8 @@ async function sendApiRequest(path, options) {
|
|
|
2561
2656
|
data: data
|
|
2562
2657
|
};
|
|
2563
2658
|
} catch (e) {
|
|
2564
|
-
|
|
2565
|
-
|
|
2659
|
+
debug$2.debugFn('error', 'Failed to parse API response JSON');
|
|
2660
|
+
debug$2.debugDir('error', e);
|
|
2566
2661
|
return {
|
|
2567
2662
|
ok: false,
|
|
2568
2663
|
message: 'API request failed',
|
|
@@ -2693,9 +2788,9 @@ cols) {
|
|
|
2693
2788
|
// Serialize the final result object before printing it
|
|
2694
2789
|
// All commands that support the --json flag should call this before printing
|
|
2695
2790
|
function serializeResultJson(data) {
|
|
2696
|
-
if (!
|
|
2791
|
+
if (!objects.isObject(data)) {
|
|
2697
2792
|
process.exitCode = 1;
|
|
2698
|
-
|
|
2793
|
+
debug$2.debugFn('inspect', {
|
|
2699
2794
|
data
|
|
2700
2795
|
});
|
|
2701
2796
|
|
|
@@ -2713,8 +2808,8 @@ function serializeResultJson(data) {
|
|
|
2713
2808
|
process.exitCode = 1;
|
|
2714
2809
|
const message = 'There was a problem converting the data set to JSON. Please try again without --json';
|
|
2715
2810
|
logger.logger.fail(message);
|
|
2716
|
-
|
|
2717
|
-
|
|
2811
|
+
debug$2.debugFn('error', 'JSON serialization failed');
|
|
2812
|
+
debug$2.debugDir('error', e);
|
|
2718
2813
|
|
|
2719
2814
|
// This could be caused by circular references, which is an "us" problem.
|
|
2720
2815
|
return `${JSON.stringify({
|
|
@@ -2979,7 +3074,7 @@ function getHelpListOutput(list, options) {
|
|
|
2979
3074
|
const names = Object.keys(list).sort(sorts.naturalCompare);
|
|
2980
3075
|
for (const name of names) {
|
|
2981
3076
|
const entry = list[name];
|
|
2982
|
-
const entryIsObj =
|
|
3077
|
+
const entryIsObj = objects.isObject(entry);
|
|
2983
3078
|
if (entryIsObj && 'hidden' in entry && entry?.hidden) {
|
|
2984
3079
|
continue;
|
|
2985
3080
|
}
|
|
@@ -3077,9 +3172,9 @@ function getAsciiHeader(command, orgFlag, compactMode = false) {
|
|
|
3077
3172
|
// Version display: show hash in debug mode, otherwise show semantic version.
|
|
3078
3173
|
const fullVersion = constants.default.ENV.INLINED_SOCKET_CLI_VERSION;
|
|
3079
3174
|
const versionHash = constants.default.ENV.INLINED_SOCKET_CLI_VERSION_HASH;
|
|
3080
|
-
const cliVersion = redacting ? REDACTED :
|
|
3175
|
+
const cliVersion = redacting ? REDACTED : debug$2.isDebug() ? versionHash : `v${fullVersion}`;
|
|
3081
3176
|
const nodeVersion = redacting ? REDACTED : process.version;
|
|
3082
|
-
const showNodeVersion = !redacting &&
|
|
3177
|
+
const showNodeVersion = !redacting && debug$2.isDebug();
|
|
3083
3178
|
const defaultOrg = getConfigValueOrUndef(constants.CONFIG_KEY_DEFAULT_ORG);
|
|
3084
3179
|
const configFromFlagDot = isConfigFromFlag() ? '*' : '.';
|
|
3085
3180
|
|
|
@@ -3197,7 +3292,7 @@ async function meowWithSubcommands(config, options) {
|
|
|
3197
3292
|
hidden: true,
|
|
3198
3293
|
description: 'Print the app version'
|
|
3199
3294
|
},
|
|
3200
|
-
...
|
|
3295
|
+
...objects.getOwn(additionalOptions, 'flags')
|
|
3201
3296
|
};
|
|
3202
3297
|
const [commandOrAliasName_, ...rawCommandArgv] = argv;
|
|
3203
3298
|
let commandOrAliasName = commandOrAliasName_;
|
|
@@ -3232,7 +3327,7 @@ async function meowWithSubcommands(config, options) {
|
|
|
3232
3327
|
}
|
|
3233
3328
|
}
|
|
3234
3329
|
if (isRootCommand) {
|
|
3235
|
-
const hiddenDebugFlag = !
|
|
3330
|
+
const hiddenDebugFlag = !debug$2.isDebug();
|
|
3236
3331
|
flags$1['compactHeader'] = {
|
|
3237
3332
|
...flags$1['compactHeader'],
|
|
3238
3333
|
hidden: false
|
|
@@ -3295,7 +3390,7 @@ async function meowWithSubcommands(config, options) {
|
|
|
3295
3390
|
spinner: spinnerFlag
|
|
3296
3391
|
} = cli1.flags;
|
|
3297
3392
|
const compactMode = compactHeaderFlag || constants.default.ENV.CI && !constants.default.ENV.VITEST;
|
|
3298
|
-
const noSpinner = spinnerFlag === false ||
|
|
3393
|
+
const noSpinner = spinnerFlag === false || debug$2.isDebug();
|
|
3299
3394
|
|
|
3300
3395
|
// Use CI spinner style when --no-spinner is passed or debug mode is enabled.
|
|
3301
3396
|
// This prevents the spinner from interfering with debug output.
|
|
@@ -3318,8 +3413,10 @@ async function meowWithSubcommands(config, options) {
|
|
|
3318
3413
|
} else {
|
|
3319
3414
|
const tokenOverride = constants.default.ENV.SOCKET_CLI_API_TOKEN;
|
|
3320
3415
|
if (tokenOverride) {
|
|
3321
|
-
//
|
|
3322
|
-
//
|
|
3416
|
+
// The env token overrides authentication only. getDefaultApiToken reads it
|
|
3417
|
+
// straight from the environment, so overrideConfigApiToken does not inject
|
|
3418
|
+
// it into the cached config and leaves the config writable ā unrelated keys
|
|
3419
|
+
// still persist, while the env token itself is never written to disk.
|
|
3323
3420
|
overrideConfigApiToken(tokenOverride);
|
|
3324
3421
|
}
|
|
3325
3422
|
}
|
|
@@ -3393,10 +3490,10 @@ async function meowWithSubcommands(config, options) {
|
|
|
3393
3490
|
} else {
|
|
3394
3491
|
lines.push('Commands');
|
|
3395
3492
|
lines.push(` ${getHelpListOutput({
|
|
3396
|
-
...
|
|
3493
|
+
...objects.toSortedObject(Object.fromEntries(Object.entries(subcommands).filter(({
|
|
3397
3494
|
1: subcommand
|
|
3398
3495
|
}) => !subcommand.hidden))),
|
|
3399
|
-
...
|
|
3496
|
+
...objects.toSortedObject(Object.fromEntries(Object.entries(aliases).filter(({
|
|
3400
3497
|
1: alias
|
|
3401
3498
|
}) => {
|
|
3402
3499
|
const {
|
|
@@ -3541,7 +3638,7 @@ function meowOrExit(config, options) {
|
|
|
3541
3638
|
version: versionFlag
|
|
3542
3639
|
} = cli.flags;
|
|
3543
3640
|
const compactMode = compactHeaderFlag || constants.default.ENV.CI && !constants.default.ENV.VITEST;
|
|
3544
|
-
const noSpinner = spinnerFlag === false ||
|
|
3641
|
+
const noSpinner = spinnerFlag === false || debug$2.isDebug();
|
|
3545
3642
|
|
|
3546
3643
|
// Use CI spinner style when --no-spinner is passed.
|
|
3547
3644
|
// This prevents the spinner from interfering with debug output.
|
|
@@ -3578,7 +3675,7 @@ function meowOrExit(config, options) {
|
|
|
3578
3675
|
}
|
|
3579
3676
|
|
|
3580
3677
|
// Meow doesn't detect 'version' as an unknown flag, so we do the leg work here.
|
|
3581
|
-
if (versionFlag && !
|
|
3678
|
+
if (versionFlag && !objects.hasOwn(cliConfig.flags, 'version')) {
|
|
3582
3679
|
// Use `console.error` here instead of `logger.error` to match Meow behavior.
|
|
3583
3680
|
console.error('Unknown flag\n--version');
|
|
3584
3681
|
// eslint-disable-next-line n/no-process-exit
|
|
@@ -3649,7 +3746,7 @@ async function fetchOrganization(options) {
|
|
|
3649
3746
|
}
|
|
3650
3747
|
sockSdk = sockSdkCResult.data;
|
|
3651
3748
|
}
|
|
3652
|
-
const orgsCResult = await handleApiCall(sockSdk.
|
|
3749
|
+
const orgsCResult = await handleApiCall(sockSdk.listOrganizations(), {
|
|
3653
3750
|
description,
|
|
3654
3751
|
silence
|
|
3655
3752
|
});
|
|
@@ -3778,7 +3875,7 @@ async function determineOrgSlug(orgFlag, interactive, dryRun) {
|
|
|
3778
3875
|
async function getDefaultOrgSlug(silence) {
|
|
3779
3876
|
const defaultOrgResult = getConfigValueOrUndef('defaultOrg');
|
|
3780
3877
|
if (defaultOrgResult) {
|
|
3781
|
-
|
|
3878
|
+
debug$2.debugFn('notice', 'use: org from "defaultOrg" value of socket/settings local app data', defaultOrgResult);
|
|
3782
3879
|
return {
|
|
3783
3880
|
ok: true,
|
|
3784
3881
|
data: defaultOrgResult
|
|
@@ -3786,7 +3883,7 @@ async function getDefaultOrgSlug(silence) {
|
|
|
3786
3883
|
}
|
|
3787
3884
|
const envOrgSlug = constants.default.ENV.SOCKET_CLI_ORG_SLUG;
|
|
3788
3885
|
if (envOrgSlug) {
|
|
3789
|
-
|
|
3886
|
+
debug$2.debugFn('notice', 'use: org from SOCKET_CLI_ORG_SLUG environment variable', envOrgSlug);
|
|
3790
3887
|
return {
|
|
3791
3888
|
ok: true,
|
|
3792
3889
|
data: envOrgSlug
|
|
@@ -3809,7 +3906,12 @@ async function getDefaultOrgSlug(silence) {
|
|
|
3809
3906
|
data: `No organization associated with the Socket API token. Unable to continue.`
|
|
3810
3907
|
};
|
|
3811
3908
|
}
|
|
3812
|
-
|
|
3909
|
+
|
|
3910
|
+
// Use the org's URL-safe `slug`, not its display `name`: this value is
|
|
3911
|
+
// exported as SOCKET_ORG_SLUG for the Coana CLI, which resolves the org by
|
|
3912
|
+
// slug. `name` is the human-readable display name (and may be null), so using
|
|
3913
|
+
// it here produced a wrong/empty org identifier.
|
|
3914
|
+
const slug = organizations[0]?.slug ?? undefined;
|
|
3813
3915
|
if (!slug) {
|
|
3814
3916
|
return {
|
|
3815
3917
|
ok: false,
|
|
@@ -3817,7 +3919,7 @@ async function getDefaultOrgSlug(silence) {
|
|
|
3817
3919
|
data: `Cannot determine the default organization for the API token. Unable to continue.`
|
|
3818
3920
|
};
|
|
3819
3921
|
}
|
|
3820
|
-
|
|
3922
|
+
debug$2.debugFn('notice', 'resolve: org from Socket API', slug);
|
|
3821
3923
|
return {
|
|
3822
3924
|
ok: true,
|
|
3823
3925
|
message: 'Retrieved default org from server',
|
|
@@ -3954,14 +4056,14 @@ async function getRepoInfo(cwd = process.cwd()) {
|
|
|
3954
4056
|
})).stdout;
|
|
3955
4057
|
info = parseGitRemoteUrl(remoteUrl);
|
|
3956
4058
|
if (!info) {
|
|
3957
|
-
|
|
3958
|
-
|
|
4059
|
+
debug$2.debugFn('warn', `Unmatched git remote URL format: ${remoteUrl}`);
|
|
4060
|
+
debug$2.debugDir('warn', {
|
|
3959
4061
|
remoteUrl
|
|
3960
4062
|
});
|
|
3961
4063
|
}
|
|
3962
4064
|
} catch (e) {
|
|
3963
4065
|
// Expected failure when not in a git repo.
|
|
3964
|
-
|
|
4066
|
+
debug$2.debugDir('inspect', {
|
|
3965
4067
|
message: 'git remote get-url failed',
|
|
3966
4068
|
error: e
|
|
3967
4069
|
});
|
|
@@ -3987,7 +4089,7 @@ async function gitBranch(cwd = process.cwd()) {
|
|
|
3987
4089
|
return gitSymbolicRefResult.stdout;
|
|
3988
4090
|
} catch (e) {
|
|
3989
4091
|
// Expected in detached HEAD state, fallback to rev-parse.
|
|
3990
|
-
|
|
4092
|
+
debug$2.debugDir('inspect', {
|
|
3991
4093
|
message: 'In detached HEAD state',
|
|
3992
4094
|
error: e
|
|
3993
4095
|
});
|
|
@@ -3999,7 +4101,7 @@ async function gitBranch(cwd = process.cwd()) {
|
|
|
3999
4101
|
return gitRevParseResult.stdout;
|
|
4000
4102
|
} catch (e) {
|
|
4001
4103
|
// Both methods failed, likely not in a git repo.
|
|
4002
|
-
|
|
4104
|
+
debug$2.debugDir('inspect', {
|
|
4003
4105
|
message: 'Unable to determine git branch',
|
|
4004
4106
|
error: e
|
|
4005
4107
|
});
|
|
@@ -4031,7 +4133,7 @@ async function detectDefaultBranch(cwd = process.cwd()) {
|
|
|
4031
4133
|
async function gitCleanFdx(cwd = process.cwd()) {
|
|
4032
4134
|
const stdioIgnoreOptions = {
|
|
4033
4135
|
cwd,
|
|
4034
|
-
stdio:
|
|
4136
|
+
stdio: debug$2.isDebug('stdio') ? 'inherit' : 'ignore'
|
|
4035
4137
|
};
|
|
4036
4138
|
try {
|
|
4037
4139
|
await spawn.spawn('git', ['clean', '-fdx'], stdioIgnoreOptions);
|
|
@@ -4047,7 +4149,7 @@ async function gitCleanFdx(cwd = process.cwd()) {
|
|
|
4047
4149
|
async function gitCheckoutBranch(branch, cwd = process.cwd()) {
|
|
4048
4150
|
const stdioIgnoreOptions = {
|
|
4049
4151
|
cwd,
|
|
4050
|
-
stdio:
|
|
4152
|
+
stdio: debug$2.isDebug('stdio') ? 'inherit' : 'ignore'
|
|
4051
4153
|
};
|
|
4052
4154
|
try {
|
|
4053
4155
|
await spawn.spawn('git', ['checkout', branch], stdioIgnoreOptions);
|
|
@@ -4066,7 +4168,7 @@ async function gitCreateBranch(branch, cwd = process.cwd()) {
|
|
|
4066
4168
|
}
|
|
4067
4169
|
const stdioIgnoreOptions = {
|
|
4068
4170
|
cwd,
|
|
4069
|
-
stdio:
|
|
4171
|
+
stdio: debug$2.isDebug('stdio') ? 'inherit' : 'ignore'
|
|
4070
4172
|
};
|
|
4071
4173
|
try {
|
|
4072
4174
|
await spawn.spawn('git', ['branch', branch], stdioIgnoreOptions);
|
|
@@ -4082,7 +4184,7 @@ async function gitCreateBranch(branch, cwd = process.cwd()) {
|
|
|
4082
4184
|
async function gitPushBranch(branch, cwd = process.cwd()) {
|
|
4083
4185
|
const stdioIgnoreOptions = {
|
|
4084
4186
|
cwd,
|
|
4085
|
-
stdio:
|
|
4187
|
+
stdio: debug$2.isDebug('stdio') ? 'inherit' : 'ignore'
|
|
4086
4188
|
};
|
|
4087
4189
|
try {
|
|
4088
4190
|
await spawn.spawn('git', ['push', '--force', '--set-upstream', 'origin', branch], stdioIgnoreOptions);
|
|
@@ -4090,9 +4192,9 @@ async function gitPushBranch(branch, cwd = process.cwd()) {
|
|
|
4090
4192
|
return true;
|
|
4091
4193
|
} catch (e) {
|
|
4092
4194
|
if (spawn.isSpawnError(e) && e.code === 128) {
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4195
|
+
debug$2.debugFn('error', "Push denied: token requires write permissions for 'contents' and 'pull-requests'");
|
|
4196
|
+
debug$2.debugDir('error', e);
|
|
4197
|
+
debug$2.debugDir('inspect', {
|
|
4096
4198
|
branch
|
|
4097
4199
|
});
|
|
4098
4200
|
} else {
|
|
@@ -4105,7 +4207,7 @@ async function gitPushBranch(branch, cwd = process.cwd()) {
|
|
|
4105
4207
|
}
|
|
4106
4208
|
async function gitCommit(commitMsg, filepaths, options) {
|
|
4107
4209
|
if (!filepaths.length) {
|
|
4108
|
-
|
|
4210
|
+
debug$2.debugFn('notice', `miss: no filepaths to add`);
|
|
4109
4211
|
return false;
|
|
4110
4212
|
}
|
|
4111
4213
|
const {
|
|
@@ -4119,7 +4221,7 @@ async function gitCommit(commitMsg, filepaths, options) {
|
|
|
4119
4221
|
await gitEnsureIdentity(user, email, cwd);
|
|
4120
4222
|
const stdioIgnoreOptions = {
|
|
4121
4223
|
cwd,
|
|
4122
|
-
stdio:
|
|
4224
|
+
stdio: debug$2.isDebug('stdio') ? 'inherit' : 'ignore'
|
|
4123
4225
|
};
|
|
4124
4226
|
try {
|
|
4125
4227
|
await spawn.spawn('git', ['add', ...filepaths], stdioIgnoreOptions);
|
|
@@ -4130,7 +4232,7 @@ async function gitCommit(commitMsg, filepaths, options) {
|
|
|
4130
4232
|
debugGit('add', false, {
|
|
4131
4233
|
error: e
|
|
4132
4234
|
});
|
|
4133
|
-
|
|
4235
|
+
debug$2.debugDir('inspect', {
|
|
4134
4236
|
filepaths
|
|
4135
4237
|
});
|
|
4136
4238
|
return false;
|
|
@@ -4143,7 +4245,7 @@ async function gitCommit(commitMsg, filepaths, options) {
|
|
|
4143
4245
|
debugGit('commit', false, {
|
|
4144
4246
|
error: e
|
|
4145
4247
|
});
|
|
4146
|
-
|
|
4248
|
+
debug$2.debugDir('inspect', {
|
|
4147
4249
|
commitMsg
|
|
4148
4250
|
});
|
|
4149
4251
|
}
|
|
@@ -4152,7 +4254,7 @@ async function gitCommit(commitMsg, filepaths, options) {
|
|
|
4152
4254
|
async function gitDeleteBranch(branch, cwd = process.cwd()) {
|
|
4153
4255
|
const stdioIgnoreOptions = {
|
|
4154
4256
|
cwd,
|
|
4155
|
-
stdio:
|
|
4257
|
+
stdio: debug$2.isDebug('stdio') ? 'inherit' : 'ignore'
|
|
4156
4258
|
};
|
|
4157
4259
|
try {
|
|
4158
4260
|
// Will throw with exit code 1 if branch does not exist.
|
|
@@ -4160,7 +4262,7 @@ async function gitDeleteBranch(branch, cwd = process.cwd()) {
|
|
|
4160
4262
|
return true;
|
|
4161
4263
|
} catch (e) {
|
|
4162
4264
|
// Expected failure when branch doesn't exist.
|
|
4163
|
-
|
|
4265
|
+
debug$2.debugDir('inspect', {
|
|
4164
4266
|
message: `Branch deletion failed (may not exist): ${branch}`,
|
|
4165
4267
|
error: e
|
|
4166
4268
|
});
|
|
@@ -4170,7 +4272,7 @@ async function gitDeleteBranch(branch, cwd = process.cwd()) {
|
|
|
4170
4272
|
async function gitDeleteRemoteBranch(branch, cwd = process.cwd()) {
|
|
4171
4273
|
const stdioIgnoreOptions = {
|
|
4172
4274
|
cwd,
|
|
4173
|
-
stdio:
|
|
4275
|
+
stdio: debug$2.isDebug('stdio') ? 'inherit' : 'ignore'
|
|
4174
4276
|
};
|
|
4175
4277
|
try {
|
|
4176
4278
|
// Will throw with exit code 1 if branch does not exist.
|
|
@@ -4178,7 +4280,7 @@ async function gitDeleteRemoteBranch(branch, cwd = process.cwd()) {
|
|
|
4178
4280
|
return true;
|
|
4179
4281
|
} catch (e) {
|
|
4180
4282
|
// Expected failure when remote branch doesn't exist.
|
|
4181
|
-
|
|
4283
|
+
debug$2.debugDir('inspect', {
|
|
4182
4284
|
message: `Remote branch deletion failed (may not exist): ${branch}`,
|
|
4183
4285
|
error: e
|
|
4184
4286
|
});
|
|
@@ -4201,7 +4303,7 @@ async function gitEnsureIdentity(name, email, cwd = process.cwd()) {
|
|
|
4201
4303
|
configValue = gitConfigResult.stdout;
|
|
4202
4304
|
} catch (e) {
|
|
4203
4305
|
// Expected when config property is not set.
|
|
4204
|
-
|
|
4306
|
+
debug$2.debugDir('inspect', {
|
|
4205
4307
|
message: `Git config property not set: ${prop}`,
|
|
4206
4308
|
error: e
|
|
4207
4309
|
});
|
|
@@ -4209,14 +4311,14 @@ async function gitEnsureIdentity(name, email, cwd = process.cwd()) {
|
|
|
4209
4311
|
if (configValue !== value) {
|
|
4210
4312
|
const stdioIgnoreOptions = {
|
|
4211
4313
|
cwd,
|
|
4212
|
-
stdio:
|
|
4314
|
+
stdio: debug$2.isDebug('stdio') ? 'inherit' : 'ignore'
|
|
4213
4315
|
};
|
|
4214
4316
|
try {
|
|
4215
4317
|
await spawn.spawn('git', ['config', prop, value], stdioIgnoreOptions);
|
|
4216
4318
|
} catch (e) {
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4319
|
+
debug$2.debugFn('warn', `Failed to set git config: ${prop}`);
|
|
4320
|
+
debug$2.debugDir('warn', e);
|
|
4321
|
+
debug$2.debugDir('inspect', {
|
|
4220
4322
|
value
|
|
4221
4323
|
});
|
|
4222
4324
|
}
|
|
@@ -4226,7 +4328,7 @@ async function gitEnsureIdentity(name, email, cwd = process.cwd()) {
|
|
|
4226
4328
|
async function gitLocalBranchExists(branch, cwd = process.cwd()) {
|
|
4227
4329
|
const stdioIgnoreOptions = {
|
|
4228
4330
|
cwd,
|
|
4229
|
-
stdio:
|
|
4331
|
+
stdio: debug$2.isDebug('stdio') ? 'inherit' : 'ignore'
|
|
4230
4332
|
};
|
|
4231
4333
|
try {
|
|
4232
4334
|
// Will throw with exit code 1 if the branch does not exist.
|
|
@@ -4246,7 +4348,7 @@ async function gitRemoteBranchExists(branch, cwd = process.cwd()) {
|
|
|
4246
4348
|
return lsRemoteResult.stdout.length > 0;
|
|
4247
4349
|
} catch (e) {
|
|
4248
4350
|
// Expected when remote is not accessible or branch doesn't exist.
|
|
4249
|
-
|
|
4351
|
+
debug$2.debugDir('inspect', {
|
|
4250
4352
|
message: `Remote branch check failed: ${branch}`,
|
|
4251
4353
|
error: e
|
|
4252
4354
|
});
|
|
@@ -4262,7 +4364,7 @@ async function gitResetAndClean(branch = 'HEAD', cwd = process.cwd()) {
|
|
|
4262
4364
|
async function gitResetHard(branch = 'HEAD', cwd = process.cwd()) {
|
|
4263
4365
|
const stdioIgnoreOptions = {
|
|
4264
4366
|
cwd,
|
|
4265
|
-
stdio:
|
|
4367
|
+
stdio: debug$2.isDebug('stdio') ? 'inherit' : 'ignore'
|
|
4266
4368
|
};
|
|
4267
4369
|
try {
|
|
4268
4370
|
await spawn.spawn('git', ['reset', '--hard', branch], stdioIgnoreOptions);
|
|
@@ -4288,8 +4390,8 @@ async function gitUnstagedModifiedFiles(cwd = process.cwd()) {
|
|
|
4288
4390
|
data: relPaths.map(p => path$1.normalizePath(p))
|
|
4289
4391
|
};
|
|
4290
4392
|
} catch (e) {
|
|
4291
|
-
|
|
4292
|
-
|
|
4393
|
+
debug$2.debugFn('error', 'Failed to get unstaged modified files');
|
|
4394
|
+
debug$2.debugDir('error', e);
|
|
4293
4395
|
return {
|
|
4294
4396
|
ok: false,
|
|
4295
4397
|
message: 'Git Error',
|
|
@@ -4359,8 +4461,16 @@ constants.NODE_MODULES,
|
|
|
4359
4461
|
// Where Node modules are installed, see <https://nodejs.org/>
|
|
4360
4462
|
// Taken from globby:
|
|
4361
4463
|
// https://github.com/sindresorhus/globby/blob/v14.0.2/ignore.js#L11-L16
|
|
4362
|
-
'flow-typed'
|
|
4464
|
+
'flow-typed',
|
|
4465
|
+
// Conventional Python virtual environment dir. Arbitrarily-named venvs are
|
|
4466
|
+
// detected via their pyvenv.cfg marker during the discovery walk below.
|
|
4467
|
+
'.venv'];
|
|
4363
4468
|
const IGNORED_DIR_PATTERNS = IGNORED_DIRS.map(i => `**/${i}`);
|
|
4469
|
+
|
|
4470
|
+
// Marker file at the root of every Python virtual environment (stdlib `venv`
|
|
4471
|
+
// per PEP 405, and virtualenv >= 20). Lets us detect venvs that don't use a
|
|
4472
|
+
// conventional directory name.
|
|
4473
|
+
const PYVENV_CFG = 'pyvenv.cfg';
|
|
4364
4474
|
async function getWorkspaceGlobs(agent, cwd = process.cwd()) {
|
|
4365
4475
|
let workspacePatterns;
|
|
4366
4476
|
if (agent === constants.PNPM) {
|
|
@@ -4481,20 +4591,49 @@ async function globWithGitIgnore(patterns, options) {
|
|
|
4481
4591
|
...options
|
|
4482
4592
|
};
|
|
4483
4593
|
const ignores = new Set(IGNORED_DIR_PATTERNS);
|
|
4594
|
+
|
|
4595
|
+
// CLI-supplied `additionalIgnores` are already anchored minimatch ā they
|
|
4596
|
+
// must not pass through the `ignore` package (whose gitignore "match
|
|
4597
|
+
// anywhere" semantics would re-interpret a bare `tests` to match
|
|
4598
|
+
// `subdir/tests/foo.json`). Keep them in fast-glob's ignore list across
|
|
4599
|
+
// both paths; only gitignore-translated entries go into the `ig` matcher.
|
|
4600
|
+
const cliMinimatchIgnores = additionalIgnores ?? [];
|
|
4484
4601
|
const projectIgnorePaths = socketConfig?.projectIgnorePaths;
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4602
|
+
const projectIgnoreGlobs = Array.isArray(projectIgnorePaths) ? ignoreFileLinesToGlobPatterns(projectIgnorePaths, path.join(cwd, '.gitignore'), cwd) : [];
|
|
4603
|
+
for (const pattern of projectIgnoreGlobs) {
|
|
4604
|
+
ignores.add(pattern);
|
|
4605
|
+
}
|
|
4606
|
+
|
|
4607
|
+
// The discovery walk (`.gitignore` files plus `pyvenv.cfg` venv markers) has
|
|
4608
|
+
// to honor the same directory exclusions as the package walk below. Otherwise
|
|
4609
|
+
// an unreadable subtree (e.g. a postgres `pgdata` dir owned by another uid, or
|
|
4610
|
+
// a Docker volume mount) makes fast-glob throw `EACCES: permission denied,
|
|
4611
|
+
// scandir` *here* ā before --exclude-paths (`cliMinimatchIgnores`) or
|
|
4612
|
+
// projectIgnorePaths are ever applied to the main walk, which is why excluding
|
|
4613
|
+
// the path did not help. `suppressErrors` is the backstop: a directory the
|
|
4614
|
+
// user simply cannot read cannot contain manifests they could scan anyway, so
|
|
4615
|
+
// skip it instead of aborting the whole `socket fix` / `socket scan` run.
|
|
4616
|
+
// Negated patterns are dropped ā for a discovery walk they could only
|
|
4617
|
+
// re-include a subtree (never prevent a crash), and fast-glob treats `!`
|
|
4618
|
+
// ignore entries inconsistently. Folding pyvenv.cfg discovery into this same
|
|
4619
|
+
// walk avoids a second full-tree traversal.
|
|
4620
|
+
const discoveryStream = vendor.outExports.globStream(['**/.gitignore', `**/${PYVENV_CFG}`], {
|
|
4492
4621
|
absolute: true,
|
|
4493
4622
|
cwd,
|
|
4494
4623
|
dot: true,
|
|
4495
|
-
ignore: DEFAULT_IGNORE_FOR_GIT_IGNORE
|
|
4624
|
+
ignore: [...DEFAULT_IGNORE_FOR_GIT_IGNORE, ...projectIgnoreGlobs, ...cliMinimatchIgnores].filter(p => p.charCodeAt(0) !== 33 /*'!'*/).map(stripTrailingSlash),
|
|
4625
|
+
suppressErrors: true
|
|
4496
4626
|
});
|
|
4497
|
-
for await (const ignorePatterns of streams.transform(
|
|
4627
|
+
for await (const ignorePatterns of streams.transform(discoveryStream, async filepath => {
|
|
4628
|
+
if (path.basename(filepath) === PYVENV_CFG) {
|
|
4629
|
+
// A pyvenv.cfg sits at the venv root, so exclude the whole directory.
|
|
4630
|
+
const relDir = path.relative(cwd, path.dirname(filepath)).replace(/\\/g, '/');
|
|
4631
|
+
// An empty relDir means the scan target itself is a venv root; don't
|
|
4632
|
+
// emit `/**`, which would exclude everything the user explicitly targeted.
|
|
4633
|
+
return relDir ? [`${relDir}/**`] : [];
|
|
4634
|
+
}
|
|
4635
|
+
return ignoreFileToGlobPatterns((await fs$1.safeReadFile(filepath)) ?? '', filepath, cwd);
|
|
4636
|
+
}, {
|
|
4498
4637
|
concurrency: 8
|
|
4499
4638
|
})) {
|
|
4500
4639
|
for (const p of ignorePatterns) {
|
|
@@ -4508,20 +4647,20 @@ async function globWithGitIgnore(patterns, options) {
|
|
|
4508
4647
|
break;
|
|
4509
4648
|
}
|
|
4510
4649
|
}
|
|
4511
|
-
|
|
4512
|
-
// CLI-supplied `additionalIgnores` are already anchored minimatch ā they
|
|
4513
|
-
// must not pass through the `ignore` package (whose gitignore "match
|
|
4514
|
-
// anywhere" semantics would re-interpret a bare `tests` to match
|
|
4515
|
-
// `subdir/tests/foo.json`). Keep them in fast-glob's ignore list across
|
|
4516
|
-
// both paths; only gitignore-translated entries go into the `ig` matcher.
|
|
4517
|
-
const cliMinimatchIgnores = additionalIgnores ?? [];
|
|
4518
4650
|
const globOptions = {
|
|
4519
4651
|
__proto__: null,
|
|
4520
4652
|
absolute: true,
|
|
4521
4653
|
cwd,
|
|
4522
4654
|
dot: true,
|
|
4523
4655
|
ignore: hasNegatedPattern ? [...globs.defaultIgnore, ...cliMinimatchIgnores] : [...ignores, ...cliMinimatchIgnores].map(stripTrailingSlash),
|
|
4524
|
-
...additionalOptions
|
|
4656
|
+
...additionalOptions,
|
|
4657
|
+
// Skip directories the running user cannot read rather than aborting the
|
|
4658
|
+
// whole walk on the first `EACCES` (see the .gitignore discovery walk
|
|
4659
|
+
// above for the full rationale). Pinned after `...additionalOptions` so a
|
|
4660
|
+
// caller's options bag cannot accidentally flip it back to `false` and
|
|
4661
|
+
// re-introduce the crash ā `suppressErrors` is a safety invariant here, not
|
|
4662
|
+
// a tunable.
|
|
4663
|
+
suppressErrors: true
|
|
4525
4664
|
};
|
|
4526
4665
|
|
|
4527
4666
|
// When no filter is provided and no negated patterns exist, use the fast path.
|
|
@@ -4614,14 +4753,14 @@ function pathsToGlobPatterns(paths, cwd) {
|
|
|
4614
4753
|
|
|
4615
4754
|
function createPurlObject(type, name, options) {
|
|
4616
4755
|
let opts;
|
|
4617
|
-
if (
|
|
4756
|
+
if (objects.isObjectObject(type)) {
|
|
4618
4757
|
opts = {
|
|
4619
4758
|
__proto__: null,
|
|
4620
4759
|
...type
|
|
4621
4760
|
};
|
|
4622
4761
|
type = opts.type;
|
|
4623
4762
|
name = opts.name;
|
|
4624
|
-
} else if (
|
|
4763
|
+
} else if (objects.isObjectObject(name)) {
|
|
4625
4764
|
opts = {
|
|
4626
4765
|
__proto__: null,
|
|
4627
4766
|
...name
|
|
@@ -4751,7 +4890,7 @@ function* walkNestedMap(map, keys = []) {
|
|
|
4751
4890
|
* Integration:
|
|
4752
4891
|
* - Works with @coana-tech/cli for reachability analysis
|
|
4753
4892
|
* - Processes socket facts JSON files
|
|
4754
|
-
* - Extracts
|
|
4893
|
+
* - Extracts full application reachability scan identifiers
|
|
4755
4894
|
*/
|
|
4756
4895
|
|
|
4757
4896
|
const {
|
|
@@ -4818,7 +4957,7 @@ async function compressSocketFactsForUpload(scanPaths) {
|
|
|
4818
4957
|
// `rm({ force: true })` no-ops on missing files, so tracking before
|
|
4819
4958
|
// creation is safe.
|
|
4820
4959
|
brPaths.push(brPath);
|
|
4821
|
-
await
|
|
4960
|
+
await require$$9.pipeline(fs.createReadStream(p), require$$11.createBrotliCompress(), fs.createWriteStream(brPath));
|
|
4822
4961
|
return brPath;
|
|
4823
4962
|
}));
|
|
4824
4963
|
const failure = results.find(r => r.status === 'rejected');
|
|
@@ -4936,6 +5075,17 @@ async function findUp(name, options) {
|
|
|
4936
5075
|
}
|
|
4937
5076
|
return undefined;
|
|
4938
5077
|
}
|
|
5078
|
+
async function withTmpDir(prefix, fn) {
|
|
5079
|
+
const tmpDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), prefix));
|
|
5080
|
+
try {
|
|
5081
|
+
return await fn(tmpDir);
|
|
5082
|
+
} finally {
|
|
5083
|
+
await fs.promises.rm(tmpDir, {
|
|
5084
|
+
recursive: true,
|
|
5085
|
+
force: true
|
|
5086
|
+
}).catch(() => {});
|
|
5087
|
+
}
|
|
5088
|
+
}
|
|
4939
5089
|
|
|
4940
5090
|
function findBinPathDetailsSync(binName) {
|
|
4941
5091
|
const rawBinPaths = bin.whichBinSync(binName, {
|
|
@@ -5132,7 +5282,7 @@ function isYarnBerry() {
|
|
|
5132
5282
|
* - Configures environment for third-party tools
|
|
5133
5283
|
*/
|
|
5134
5284
|
|
|
5135
|
-
const require$2 = require$$
|
|
5285
|
+
const require$2 = require$$1.createRequire((typeof document === 'undefined' ? require$$0$1.pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('utils.js', document.baseURI).href)));
|
|
5136
5286
|
const {
|
|
5137
5287
|
PACKAGE_LOCK_JSON,
|
|
5138
5288
|
PNPM_LOCK_YAML,
|
|
@@ -5194,20 +5344,27 @@ async function spawnDlx(packageSpec, args, options, spawnExtra) {
|
|
|
5194
5344
|
spawnArgs.push(constants.FLAG_SILENT);
|
|
5195
5345
|
}
|
|
5196
5346
|
spawnArgs.push('dlx');
|
|
5347
|
+
// Never let the target project's `.pnpmfile.cjs` hooks run while we launch
|
|
5348
|
+
// a third-party tool via `pnpm dlx`. In a pnpm workspace root, `pnpm dlx`
|
|
5349
|
+
// loads the cwd's `.pnpmfile.cjs`, so a broken hook there (e.g. a `require`
|
|
5350
|
+
// of an unresolved Git LFS pointer) crashes the launcher with a bare exit
|
|
5351
|
+
// code before our tool ever starts. The dlx tool installs into an isolated
|
|
5352
|
+
// store, so the project's install hooks are irrelevant to it. pnpm honors
|
|
5353
|
+
// this only as a config setting, not as a `dlx` CLI flag, so it must be set
|
|
5354
|
+
// via the npm_config_ env var. See: https://pnpm.io/npmrc#settings
|
|
5355
|
+
const pnpmEnv = {
|
|
5356
|
+
...objects.getOwn(finalShadowOptions, 'env'),
|
|
5357
|
+
npm_config_ignore_pnpmfile: 'true'
|
|
5358
|
+
};
|
|
5197
5359
|
if (force) {
|
|
5198
|
-
//
|
|
5199
|
-
// This ensures we always get the latest version within the range.
|
|
5200
|
-
|
|
5201
|
-
...finalShadowOptions,
|
|
5202
|
-
env: {
|
|
5203
|
-
...require$$11.getOwn(finalShadowOptions, 'env'),
|
|
5204
|
-
// Set dlx cache max age to 0 minutes to bypass cache.
|
|
5205
|
-
// The npm_config_ prefix is how pnpm reads config from environment variables.
|
|
5206
|
-
// See: https://pnpm.io/npmrc#settings
|
|
5207
|
-
npm_config_dlx_cache_max_age: '0'
|
|
5208
|
-
}
|
|
5209
|
-
};
|
|
5360
|
+
// Set dlx-cache-max-age to 0 minutes to bypass cache and force a fresh
|
|
5361
|
+
// download. This ensures we always get the latest version within the range.
|
|
5362
|
+
pnpmEnv['npm_config_dlx_cache_max_age'] = '0';
|
|
5210
5363
|
}
|
|
5364
|
+
finalShadowOptions = {
|
|
5365
|
+
...finalShadowOptions,
|
|
5366
|
+
env: pnpmEnv
|
|
5367
|
+
};
|
|
5211
5368
|
spawnArgs.push(packageString, ...args);
|
|
5212
5369
|
const shadowPnpmBin = /*@__PURE__*/require$2(constants.default.shadowPnpmBinPath);
|
|
5213
5370
|
return await shadowPnpmBin(spawnArgs, finalShadowOptions, spawnExtra);
|
|
@@ -5224,7 +5381,7 @@ async function spawnDlx(packageSpec, args, options, spawnExtra) {
|
|
|
5224
5381
|
finalShadowOptions = {
|
|
5225
5382
|
...finalShadowOptions,
|
|
5226
5383
|
env: {
|
|
5227
|
-
...
|
|
5384
|
+
...objects.getOwn(finalShadowOptions, 'env'),
|
|
5228
5385
|
YARN_NODE_LINKER: 'node-modules'
|
|
5229
5386
|
}
|
|
5230
5387
|
};
|
|
@@ -5254,6 +5411,30 @@ async function spawnDlx(packageSpec, args, options, spawnExtra) {
|
|
|
5254
5411
|
*/
|
|
5255
5412
|
const installedCoanaScriptPathsByVersion = new Map();
|
|
5256
5413
|
|
|
5414
|
+
/**
|
|
5415
|
+
* Strip npm-injected `npm_package_*` env vars before spawning a Coana
|
|
5416
|
+
* subprocess. npm (and pnpm/yarn classic) populate one env var per leaf in
|
|
5417
|
+
* the cwd's package.json ā `npm_package_dependencies_*`, `npm_package_scripts_*`,
|
|
5418
|
+
* etc. In big monorepos with hundreds of deps this can easily account for
|
|
5419
|
+
* 50KB+ of environment, pushing combined argv + env past Linux ARG_MAX
|
|
5420
|
+
* (~128KB) and causing `spawn` to fail with E2BIG before Coana even starts.
|
|
5421
|
+
*
|
|
5422
|
+
* Coana does not read `npm_package_*` itself, so dropping them is safe. We
|
|
5423
|
+
* intentionally keep `npm_config_*` (registry, cache, proxy settings sourced
|
|
5424
|
+
* from .npmrc), `npm_lifecycle_*`, and everything else untouched ā those can
|
|
5425
|
+
* matter for outbound network behavior of nested `npm install` calls.
|
|
5426
|
+
*/
|
|
5427
|
+
function sanitizeEnvForCoanaSubprocess(env) {
|
|
5428
|
+
const out = {};
|
|
5429
|
+
for (const key of Object.keys(env)) {
|
|
5430
|
+
if (key.startsWith('npm_package_')) {
|
|
5431
|
+
continue;
|
|
5432
|
+
}
|
|
5433
|
+
out[key] = env[key];
|
|
5434
|
+
}
|
|
5435
|
+
return out;
|
|
5436
|
+
}
|
|
5437
|
+
|
|
5257
5438
|
/**
|
|
5258
5439
|
* Spawn an installed Coana entry point via `node` (or directly, if it's a
|
|
5259
5440
|
* native binary). Shared by the SOCKET_CLI_COANA_LOCAL_PATH branch and the
|
|
@@ -5264,8 +5445,8 @@ async function spawnCoanaScriptViaNode(scriptPath, args, finalEnv, options, spaw
|
|
|
5264
5445
|
const spawnArgs = isBinary ? args : [scriptPath, ...args];
|
|
5265
5446
|
const spawnResult = await spawn.spawn(isBinary ? scriptPath : 'node', spawnArgs, {
|
|
5266
5447
|
cwd: options.cwd,
|
|
5267
|
-
env: finalEnv,
|
|
5268
|
-
stdio: spawnExtra?.['stdio']
|
|
5448
|
+
env: sanitizeEnvForCoanaSubprocess(finalEnv),
|
|
5449
|
+
stdio: options.stdio ?? spawnExtra?.['stdio'] ?? 'inherit'
|
|
5269
5450
|
});
|
|
5270
5451
|
return {
|
|
5271
5452
|
ok: true,
|
|
@@ -5309,7 +5490,7 @@ async function installCoanaToTmpdir(version, finalEnv) {
|
|
|
5309
5490
|
}
|
|
5310
5491
|
const installDir = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'socket-coana-'));
|
|
5311
5492
|
await spawn.spawn('npm', ['install', '--no-save', '--no-package-lock', '--no-audit', '--no-fund', '--prefix', installDir, `@coana-tech/cli@${version}`], {
|
|
5312
|
-
env: finalEnv,
|
|
5493
|
+
env: sanitizeEnvForCoanaSubprocess(finalEnv),
|
|
5313
5494
|
stdio: 'inherit'
|
|
5314
5495
|
});
|
|
5315
5496
|
const scriptPath = await resolveCoanaBinFromInstallDir(installDir);
|
|
@@ -5341,6 +5522,38 @@ async function spawnCoanaViaNpmInstall(args, version, finalEnv, options, spawnEx
|
|
|
5341
5522
|
return buildDlxErrorResult(e);
|
|
5342
5523
|
}
|
|
5343
5524
|
}
|
|
5525
|
+
/**
|
|
5526
|
+
* Resolve how the Coana engine should be launched.
|
|
5527
|
+
*
|
|
5528
|
+
* SOCKET_CLI_COANA_LAUNCHER wins when set:
|
|
5529
|
+
* - 'auto' (default): try dlx first, fall back to `npm install` + `node` on
|
|
5530
|
+
* launcher-level failures.
|
|
5531
|
+
* - 'npm-install': skip dlx entirely; always `npm install` + `node`.
|
|
5532
|
+
* - 'npx': dlx only; never fall back.
|
|
5533
|
+
* Unrecognized values warn and behave as 'auto'.
|
|
5534
|
+
*
|
|
5535
|
+
* The legacy boolean variables SOCKET_CLI_COANA_FORCE_NPM_INSTALL
|
|
5536
|
+
* ('npm-install') and SOCKET_CLI_COANA_DISABLE_NPM_FALLBACK ('npx') are still
|
|
5537
|
+
* honored when the new variable is unset, but are intentionally undocumented.
|
|
5538
|
+
*/
|
|
5539
|
+
function getCoanaLauncherMode() {
|
|
5540
|
+
const rawMode = process.env['SOCKET_CLI_COANA_LAUNCHER'];
|
|
5541
|
+
const mode = rawMode?.trim().toLowerCase();
|
|
5542
|
+
if (mode) {
|
|
5543
|
+
if (mode === 'auto' || mode === 'npm-install' || mode === 'npx') {
|
|
5544
|
+
return mode;
|
|
5545
|
+
}
|
|
5546
|
+
logger.logger.warn(`Ignoring unrecognized SOCKET_CLI_COANA_LAUNCHER value "${rawMode}"; expected "auto", "npm-install", or "npx".`);
|
|
5547
|
+
return 'auto';
|
|
5548
|
+
}
|
|
5549
|
+
if (process.env['SOCKET_CLI_COANA_FORCE_NPM_INSTALL']) {
|
|
5550
|
+
return 'npm-install';
|
|
5551
|
+
}
|
|
5552
|
+
if (process.env['SOCKET_CLI_COANA_DISABLE_NPM_FALLBACK']) {
|
|
5553
|
+
return 'npx';
|
|
5554
|
+
}
|
|
5555
|
+
return 'auto';
|
|
5556
|
+
}
|
|
5344
5557
|
|
|
5345
5558
|
/**
|
|
5346
5559
|
* Helper to spawn coana with dlx.
|
|
@@ -5352,9 +5565,10 @@ async function spawnCoanaViaNpmInstall(args, version, finalEnv, options, spawnEx
|
|
|
5352
5565
|
*
|
|
5353
5566
|
* If the dlx path fails (e.g. broken `npx` on the host), falls back to
|
|
5354
5567
|
* `npm install`-ing @coana-tech/cli into a temp directory and invoking it
|
|
5355
|
-
* directly via `node`. The
|
|
5356
|
-
*
|
|
5357
|
-
*
|
|
5568
|
+
* directly via `node`. The launcher strategy can be overridden with
|
|
5569
|
+
* SOCKET_CLI_COANA_LAUNCHER: 'auto' (the default) tries dlx with the
|
|
5570
|
+
* npm-install fallback, 'npm-install' skips dlx entirely, and 'npx' never
|
|
5571
|
+
* falls back.
|
|
5358
5572
|
*/
|
|
5359
5573
|
async function spawnCoanaDlx(args, orgSlug, options, spawnExtra) {
|
|
5360
5574
|
const {
|
|
@@ -5369,9 +5583,8 @@ async function spawnCoanaDlx(args, orgSlug, options, spawnExtra) {
|
|
|
5369
5583
|
const mixinsEnv = {
|
|
5370
5584
|
SOCKET_CLI_VERSION: constants.default.ENV.INLINED_SOCKET_CLI_VERSION,
|
|
5371
5585
|
// Forwarded to the Coana CLI so it can append our product token to its
|
|
5372
|
-
// outbound axios User-Agent header.
|
|
5373
|
-
|
|
5374
|
-
SOCKET_CALLER_USER_AGENT: `socket/${constants.default.ENV.INLINED_SOCKET_CLI_VERSION} node/${process.version} ${process.platform}/${process.arch}`
|
|
5586
|
+
// outbound axios User-Agent header.
|
|
5587
|
+
SOCKET_CALLER_USER_AGENT: getCliUserAgent()
|
|
5375
5588
|
};
|
|
5376
5589
|
const defaultApiToken = getDefaultApiToken();
|
|
5377
5590
|
if (defaultApiToken) {
|
|
@@ -5396,23 +5609,38 @@ async function spawnCoanaDlx(args, orgSlug, options, spawnExtra) {
|
|
|
5396
5609
|
...spawnEnv
|
|
5397
5610
|
};
|
|
5398
5611
|
const resolvedVersion = coanaVersion || constants.default.ENV.INLINED_SOCKET_CLI_COANA_TECH_CLI_VERSION;
|
|
5612
|
+
|
|
5613
|
+
// `shadowNpmBase` (the dlx launcher) configures the child's stdio from its
|
|
5614
|
+
// `options` arg, NOT from the registry-spawn `extra` arg ā the latter only
|
|
5615
|
+
// attaches metadata to the result. Callers that requested streaming via
|
|
5616
|
+
// `spawnExtra` (the 4th arg), e.g. `{ stdio: 'inherit' }` from
|
|
5617
|
+
// `socket manifest gradle`, were therefore silently ignored on this path:
|
|
5618
|
+
// Coana ran piped and its output ā including the real failure reason ā never
|
|
5619
|
+
// reached the user, leaving only an unhelpful "command failed". Resolve the
|
|
5620
|
+
// requested stdio from either argument and honor it on every launch path:
|
|
5621
|
+
// dlx, local-path, and npm-install (e.g. `socket fix --silence` requests
|
|
5622
|
+
// `stdio: 'pipe'` via options).
|
|
5623
|
+
const requestedStdio = spawnExtra?.['stdio'] ?? objects.getOwn(dlxOptions, 'stdio');
|
|
5399
5624
|
const localCoanaPath = process.env['SOCKET_CLI_COANA_LOCAL_PATH'];
|
|
5400
5625
|
// Use local Coana CLI if path is provided.
|
|
5401
5626
|
if (localCoanaPath) {
|
|
5402
5627
|
try {
|
|
5403
5628
|
return await spawnCoanaScriptViaNode(localCoanaPath, args, finalEnv, {
|
|
5404
|
-
cwd: dlxOptions.cwd
|
|
5629
|
+
cwd: dlxOptions.cwd,
|
|
5630
|
+
stdio: requestedStdio
|
|
5405
5631
|
}, spawnExtra);
|
|
5406
5632
|
} catch (e) {
|
|
5407
5633
|
return buildDlxErrorResult(e);
|
|
5408
5634
|
}
|
|
5409
5635
|
}
|
|
5636
|
+
const launcherMode = getCoanaLauncherMode();
|
|
5410
5637
|
|
|
5411
5638
|
// Allow forcing the npm-install path for debugging or for environments
|
|
5412
5639
|
// where dlx is known-broken.
|
|
5413
|
-
if (
|
|
5640
|
+
if (launcherMode === 'npm-install') {
|
|
5414
5641
|
return await spawnCoanaViaNpmInstall(args, resolvedVersion, finalEnv, {
|
|
5415
|
-
cwd: dlxOptions.cwd
|
|
5642
|
+
cwd: dlxOptions.cwd,
|
|
5643
|
+
stdio: requestedStdio
|
|
5416
5644
|
}, spawnExtra);
|
|
5417
5645
|
}
|
|
5418
5646
|
try {
|
|
@@ -5422,8 +5650,16 @@ async function spawnCoanaDlx(args, orgSlug, options, spawnExtra) {
|
|
|
5422
5650
|
version: resolvedVersion
|
|
5423
5651
|
}, args, {
|
|
5424
5652
|
force: true,
|
|
5425
|
-
silent
|
|
5653
|
+
// Do NOT silence the launcher. `--silent` (npm loglevel silent) hides
|
|
5654
|
+
// npm's own download/registry/launch errors, so when npx/pnpm-dlx fails
|
|
5655
|
+
// to fetch @coana-tech/cli the user is left with a bare exit code and no
|
|
5656
|
+
// cause. shadowNpmBase defaults to `--loglevel error`, which keeps real
|
|
5657
|
+
// launcher errors visible while staying quiet on success.
|
|
5658
|
+
silent: false,
|
|
5426
5659
|
...dlxOptions,
|
|
5660
|
+
...(requestedStdio === undefined ? {} : {
|
|
5661
|
+
stdio: requestedStdio
|
|
5662
|
+
}),
|
|
5427
5663
|
env: finalEnv,
|
|
5428
5664
|
ipc: {
|
|
5429
5665
|
[constants.default.SOCKET_CLI_SHADOW_ACCEPT_RISKS]: true,
|
|
@@ -5439,7 +5675,7 @@ async function spawnCoanaDlx(args, orgSlug, options, spawnExtra) {
|
|
|
5439
5675
|
};
|
|
5440
5676
|
} catch (e) {
|
|
5441
5677
|
const dlxError = buildDlxErrorResult(e);
|
|
5442
|
-
if (
|
|
5678
|
+
if (launcherMode === 'npx') {
|
|
5443
5679
|
return dlxError;
|
|
5444
5680
|
}
|
|
5445
5681
|
|
|
@@ -5449,9 +5685,10 @@ async function spawnCoanaDlx(args, orgSlug, options, spawnExtra) {
|
|
|
5449
5685
|
if (!shouldFallbackOnDlxError(e)) {
|
|
5450
5686
|
return dlxError;
|
|
5451
5687
|
}
|
|
5452
|
-
logger.logger.warn('Coana dlx invocation failed
|
|
5688
|
+
logger.logger.warn('Coana dlx invocation failed; retrying via `npm install` + `node`.');
|
|
5453
5689
|
const fallbackResult = await spawnCoanaViaNpmInstall(args, resolvedVersion, finalEnv, {
|
|
5454
|
-
cwd: dlxOptions.cwd
|
|
5690
|
+
cwd: dlxOptions.cwd,
|
|
5691
|
+
stdio: requestedStdio
|
|
5455
5692
|
}, spawnExtra);
|
|
5456
5693
|
if (fallbackResult.ok) {
|
|
5457
5694
|
return fallbackResult;
|
|
@@ -5485,10 +5722,29 @@ async function spawnCoanaDlx(args, orgSlug, options, spawnExtra) {
|
|
|
5485
5722
|
* rather than blindly re-running Coana.
|
|
5486
5723
|
*/
|
|
5487
5724
|
function shouldFallbackOnDlxError(e) {
|
|
5488
|
-
|
|
5489
|
-
|
|
5725
|
+
// Coana clearly ran (its banner is in the captured stderr) ā any later
|
|
5726
|
+
// non-zero exit is a real Coana failure and retrying would hit it again.
|
|
5727
|
+
if (coanaBannerSeen(e)) {
|
|
5490
5728
|
return false;
|
|
5491
5729
|
}
|
|
5730
|
+
return dlxLauncherFailedBeforeCoana(e);
|
|
5731
|
+
}
|
|
5732
|
+
|
|
5733
|
+
/**
|
|
5734
|
+
* Heuristic: did the dlx launcher (npx / pnpm dlx / yarn dlx) fail BEFORE the
|
|
5735
|
+
* Coana process itself started? True for spawn-level errors (a string `code`
|
|
5736
|
+
* like ENOENT), signal kills, and exit codes >= 128 (conventionally
|
|
5737
|
+
* signal-derived) ā all cases where the launcher, not Coana, is the culprit
|
|
5738
|
+
* (e.g. npx missing from PATH, or @coana-tech/cli failing to download). A small
|
|
5739
|
+
* integer exit code is deliberately NOT treated as a launch failure: Coana's
|
|
5740
|
+
* own exit codes are small integers too, so it is genuinely ambiguous.
|
|
5741
|
+
*
|
|
5742
|
+
* Caveat: a launcher that fails to download the package can also exit with a
|
|
5743
|
+
* small integer (npm/npx often exit 1), which lands in the ambiguous bucket.
|
|
5744
|
+
* We cannot disambiguate those from a real Coana exit without inspecting the
|
|
5745
|
+
* launcher's output, so the npm-install fallback does not fire for them.
|
|
5746
|
+
*/
|
|
5747
|
+
function dlxLauncherFailedBeforeCoana(e) {
|
|
5492
5748
|
const code = e?.code;
|
|
5493
5749
|
// Spawn-level failure (e.g. ENOENT when npx is missing from PATH).
|
|
5494
5750
|
if (typeof code === 'string') {
|
|
@@ -5500,10 +5756,18 @@ function shouldFallbackOnDlxError(e) {
|
|
|
5500
5756
|
}
|
|
5501
5757
|
// Exit codes >= 128 are conventionally signal-derived, and the observed
|
|
5502
5758
|
// npx-launcher failures in the wild fall into this range (e.g. 249, 254).
|
|
5503
|
-
|
|
5504
|
-
|
|
5505
|
-
|
|
5506
|
-
|
|
5759
|
+
return typeof code === 'number' && code >= 128;
|
|
5760
|
+
}
|
|
5761
|
+
|
|
5762
|
+
/**
|
|
5763
|
+
* Definitive proof Coana actually booted: its startup banner appears in the
|
|
5764
|
+
* captured stderr. Only available when the launcher's output was piped
|
|
5765
|
+
* (captured); with inherited stdio there is nothing to inspect, so this
|
|
5766
|
+
* returns false (the failure is then classified by exit code / signal alone).
|
|
5767
|
+
*/
|
|
5768
|
+
function coanaBannerSeen(e) {
|
|
5769
|
+
const capturedStderr = String(e?.stderr ?? '');
|
|
5770
|
+
return !!capturedStderr && /Coana CLI version/i.test(capturedStderr);
|
|
5507
5771
|
}
|
|
5508
5772
|
|
|
5509
5773
|
/**
|
|
@@ -5512,6 +5776,7 @@ function shouldFallbackOnDlxError(e) {
|
|
|
5512
5776
|
*/
|
|
5513
5777
|
function buildDlxErrorResult(e) {
|
|
5514
5778
|
const stderr = e?.stderr;
|
|
5779
|
+
const stdout = e?.stdout;
|
|
5515
5780
|
const exitCode = e?.code;
|
|
5516
5781
|
const signal = e?.signal;
|
|
5517
5782
|
const cause = getErrorCause(e);
|
|
@@ -5523,7 +5788,29 @@ function buildDlxErrorResult(e) {
|
|
|
5523
5788
|
details.push(`signal ${signal}`);
|
|
5524
5789
|
}
|
|
5525
5790
|
const detailSuffix = details.length ? ` (${details.join(', ')})` : '';
|
|
5526
|
-
|
|
5791
|
+
// Prefer captured stderr, then stdout, then the generic spawn error. Coana
|
|
5792
|
+
// logs some failures (e.g. unresolved Gradle dependencies) to stdout, so
|
|
5793
|
+
// without the stdout fallback a piped failure collapsed to an unhelpful
|
|
5794
|
+
// "command failed" even when the real reason was captured.
|
|
5795
|
+
const detail = stderr || stdout || cause;
|
|
5796
|
+
// Be honest about WHERE the failure happened. On the dlx path the spawned
|
|
5797
|
+
// process is the package-manager launcher (npx / pnpm dlx / yarn dlx), which
|
|
5798
|
+
// downloads @coana-tech/cli and only then runs it ā so a failure may be the
|
|
5799
|
+
// launcher dying before Coana ever started, not Coana itself. We can only be
|
|
5800
|
+
// CERTAIN of that for a spawn-level error (a string `code` like ENOENT: the
|
|
5801
|
+
// launcher binary could not start, so Coana provably never ran). A non-zero
|
|
5802
|
+
// exit or signal is genuinely ambiguous ā Coana may have started, streamed
|
|
5803
|
+
// output, and then died (e.g. OOM), or the launcher may have failed to fetch
|
|
5804
|
+
// the package ā and with inherited stdio there is no captured output to tell
|
|
5805
|
+
// them apart, so we must not assert either way.
|
|
5806
|
+
let message;
|
|
5807
|
+
if (coanaBannerSeen(e)) {
|
|
5808
|
+
message = `Coana command failed${detailSuffix}: ${detail}`;
|
|
5809
|
+
} else if (typeof e?.code === 'string') {
|
|
5810
|
+
message = `Failed to launch Coana via the package manager${detailSuffix} ā the npx/pnpm-dlx/yarn-dlx launcher could not start (e.g. it is missing from PATH): ${detail}`;
|
|
5811
|
+
} else {
|
|
5812
|
+
message = `Coana failed to run via the package manager${detailSuffix}: ${detail}`;
|
|
5813
|
+
}
|
|
5527
5814
|
return {
|
|
5528
5815
|
ok: false,
|
|
5529
5816
|
data: e,
|
|
@@ -5622,7 +5909,7 @@ function getDefaultSocketJson() {
|
|
|
5622
5909
|
function readSocketJsonSync(cwd, defaultOnError = false) {
|
|
5623
5910
|
const sockJsonPath = path.join(cwd, constants.SOCKET_JSON);
|
|
5624
5911
|
if (!fs.existsSync(sockJsonPath)) {
|
|
5625
|
-
|
|
5912
|
+
debug$2.debugFn('notice', `miss: ${constants.SOCKET_JSON} not found at ${cwd}`);
|
|
5626
5913
|
return {
|
|
5627
5914
|
ok: true,
|
|
5628
5915
|
data: getDefaultSocketJson()
|
|
@@ -5634,16 +5921,16 @@ function readSocketJsonSync(cwd, defaultOnError = false) {
|
|
|
5634
5921
|
} catch (e) {
|
|
5635
5922
|
if (defaultOnError) {
|
|
5636
5923
|
logger.logger.warn(`Failed to read ${constants.SOCKET_JSON}, using default`);
|
|
5637
|
-
|
|
5638
|
-
|
|
5924
|
+
debug$2.debugFn('warn', `Failed to read ${constants.SOCKET_JSON} sync`);
|
|
5925
|
+
debug$2.debugDir('warn', e);
|
|
5639
5926
|
return {
|
|
5640
5927
|
ok: true,
|
|
5641
5928
|
data: getDefaultSocketJson()
|
|
5642
5929
|
};
|
|
5643
5930
|
}
|
|
5644
5931
|
const cause = formatErrorWithDetail(`An error occurred while trying to read ${constants.SOCKET_JSON}`, e);
|
|
5645
|
-
|
|
5646
|
-
|
|
5932
|
+
debug$2.debugFn('error', `Failed to read ${constants.SOCKET_JSON} sync`);
|
|
5933
|
+
debug$2.debugDir('error', e);
|
|
5647
5934
|
return {
|
|
5648
5935
|
ok: false,
|
|
5649
5936
|
message: `Failed to read ${constants.SOCKET_JSON}`,
|
|
@@ -5654,11 +5941,11 @@ function readSocketJsonSync(cwd, defaultOnError = false) {
|
|
|
5654
5941
|
try {
|
|
5655
5942
|
jsonObj = JSON.parse(jsonContent);
|
|
5656
5943
|
} catch (e) {
|
|
5657
|
-
|
|
5658
|
-
|
|
5944
|
+
debug$2.debugFn('error', `Failed to parse ${constants.SOCKET_JSON} as JSON (sync)`);
|
|
5945
|
+
debug$2.debugDir('inspect', {
|
|
5659
5946
|
jsonContent
|
|
5660
5947
|
});
|
|
5661
|
-
|
|
5948
|
+
debug$2.debugDir('error', e);
|
|
5662
5949
|
if (defaultOnError) {
|
|
5663
5950
|
logger.logger.warn(`Failed to parse ${constants.SOCKET_JSON}, using default`);
|
|
5664
5951
|
return {
|
|
@@ -5692,11 +5979,11 @@ async function writeSocketJson(cwd, sockJson) {
|
|
|
5692
5979
|
try {
|
|
5693
5980
|
jsonContent = JSON.stringify(sockJson, null, 2);
|
|
5694
5981
|
} catch (e) {
|
|
5695
|
-
|
|
5696
|
-
|
|
5982
|
+
debug$2.debugFn('error', `Failed to serialize ${constants.SOCKET_JSON} to JSON`);
|
|
5983
|
+
debug$2.debugDir('inspect', {
|
|
5697
5984
|
sockJson
|
|
5698
5985
|
});
|
|
5699
|
-
|
|
5986
|
+
debug$2.debugDir('error', e);
|
|
5700
5987
|
return {
|
|
5701
5988
|
ok: false,
|
|
5702
5989
|
message: 'Failed to serialize to JSON',
|
|
@@ -5812,12 +6099,12 @@ async function fetchGhsaDetails(ids) {
|
|
|
5812
6099
|
if (advisory && advisory.ghsaId) {
|
|
5813
6100
|
results.set(id, advisory);
|
|
5814
6101
|
} else {
|
|
5815
|
-
|
|
6102
|
+
debug$2.debugFn('notice', `miss: no advisory found for ${id}`);
|
|
5816
6103
|
}
|
|
5817
6104
|
}
|
|
5818
6105
|
} catch (e) {
|
|
5819
|
-
|
|
5820
|
-
|
|
6106
|
+
debug$2.debugFn('error', formatErrorWithDetail('Failed to fetch GHSA details', e));
|
|
6107
|
+
debug$2.debugDir('error', e);
|
|
5821
6108
|
}
|
|
5822
6109
|
return results;
|
|
5823
6110
|
}
|
|
@@ -5828,13 +6115,13 @@ function getOctokit() {
|
|
|
5828
6115
|
SOCKET_CLI_GITHUB_TOKEN
|
|
5829
6116
|
} = constants.default.ENV;
|
|
5830
6117
|
if (!SOCKET_CLI_GITHUB_TOKEN) {
|
|
5831
|
-
|
|
6118
|
+
debug$2.debugFn('notice', 'miss: SOCKET_CLI_GITHUB_TOKEN env var');
|
|
5832
6119
|
}
|
|
5833
6120
|
const octokitOptions = {
|
|
5834
6121
|
auth: SOCKET_CLI_GITHUB_TOKEN,
|
|
5835
6122
|
baseUrl: constants.default.ENV.GITHUB_API_URL
|
|
5836
6123
|
};
|
|
5837
|
-
|
|
6124
|
+
debug$2.debugDir('inspect', {
|
|
5838
6125
|
octokitOptions
|
|
5839
6126
|
});
|
|
5840
6127
|
_octokit = new vendor.Octokit(octokitOptions);
|
|
@@ -5848,7 +6135,7 @@ function getOctokitGraphql() {
|
|
|
5848
6135
|
SOCKET_CLI_GITHUB_TOKEN
|
|
5849
6136
|
} = constants.default.ENV;
|
|
5850
6137
|
if (!SOCKET_CLI_GITHUB_TOKEN) {
|
|
5851
|
-
|
|
6138
|
+
debug$2.debugFn('notice', 'miss: SOCKET_CLI_GITHUB_TOKEN env var');
|
|
5852
6139
|
}
|
|
5853
6140
|
_octokitGraphql = vendor.graphql2.defaults({
|
|
5854
6141
|
headers: {
|
|
@@ -5901,31 +6188,31 @@ async function setGitRemoteGithubRepoUrl(owner, repo, token, cwd = process.cwd()
|
|
|
5901
6188
|
const {
|
|
5902
6189
|
GITHUB_SERVER_URL
|
|
5903
6190
|
} = constants.default.ENV;
|
|
5904
|
-
const urlObj =
|
|
6191
|
+
const urlObj = url.parseUrl(GITHUB_SERVER_URL);
|
|
5905
6192
|
const host = urlObj?.host;
|
|
5906
6193
|
if (!host) {
|
|
5907
|
-
|
|
5908
|
-
|
|
6194
|
+
debug$2.debugFn('error', 'invalid: GITHUB_SERVER_URL env var');
|
|
6195
|
+
debug$2.debugDir('inspect', {
|
|
5909
6196
|
GITHUB_SERVER_URL
|
|
5910
6197
|
});
|
|
5911
6198
|
return false;
|
|
5912
6199
|
}
|
|
5913
|
-
const url = `https://x-access-token:${token}@${host}/${owner}/${repo}`;
|
|
6200
|
+
const url$1 = `https://x-access-token:${token}@${host}/${owner}/${repo}`;
|
|
5914
6201
|
const stdioIgnoreOptions = {
|
|
5915
6202
|
cwd,
|
|
5916
|
-
stdio:
|
|
6203
|
+
stdio: debug$2.isDebug('stdio') ? 'inherit' : 'ignore'
|
|
5917
6204
|
};
|
|
5918
|
-
const quotedCmd = `\`git remote set-url origin ${url}\``;
|
|
5919
|
-
|
|
6205
|
+
const quotedCmd = `\`git remote set-url origin ${url$1}\``;
|
|
6206
|
+
debug$2.debugFn('stdio', `spawn: ${quotedCmd}`);
|
|
5920
6207
|
try {
|
|
5921
|
-
await spawn.spawn('git', ['remote', 'set-url', 'origin', url], stdioIgnoreOptions);
|
|
6208
|
+
await spawn.spawn('git', ['remote', 'set-url', 'origin', url$1], stdioIgnoreOptions);
|
|
5922
6209
|
return true;
|
|
5923
6210
|
} catch (e) {
|
|
5924
|
-
|
|
5925
|
-
|
|
6211
|
+
debug$2.debugFn('error', `Git command failed: ${quotedCmd}`);
|
|
6212
|
+
debug$2.debugDir('inspect', {
|
|
5926
6213
|
cmd: quotedCmd
|
|
5927
6214
|
});
|
|
5928
|
-
|
|
6215
|
+
debug$2.debugDir('error', e);
|
|
5929
6216
|
}
|
|
5930
6217
|
return false;
|
|
5931
6218
|
}
|
|
@@ -6218,11 +6505,31 @@ function isPnpmLockfileScanCommand(command) {
|
|
|
6218
6505
|
// export type _Check_EcosystemString_has_all_purl_types =
|
|
6219
6506
|
// ExpectNever<MissingInEcosystemString>
|
|
6220
6507
|
|
|
6221
|
-
const ALL_ECOSYSTEMS = ['alpm', 'apk', 'bitbucket', 'cargo', 'chrome', 'cocoapods', 'composer', 'conan', 'conda', 'cran', 'deb', 'docker', 'gem', 'generic', 'github', 'golang', 'hackage', 'hex', 'huggingface', 'maven', 'mlflow', constants.NPM, 'nuget', 'oci', 'pub', 'pypi', 'qpkg', 'rpm', 'swift', 'swid', 'unknown', 'vscode'];
|
|
6508
|
+
const ALL_ECOSYSTEMS = ['alpm', 'apk', 'bitbucket', 'cargo', 'chrome', 'clawhub', 'cocoapods', 'composer', 'conan', 'conda', 'cran', 'deb', 'docker', 'gem', 'generic', 'github', 'golang', 'hackage', 'hex', 'huggingface', 'maven', 'mlflow', constants.NPM, 'nuget', 'oci', 'pub', 'pypi', 'qpkg', 'rpm', 'socket', 'swift', 'swid', 'unknown', 'vscode'];
|
|
6222
6509
|
new Set(ALL_ECOSYSTEMS);
|
|
6510
|
+
|
|
6511
|
+
// Purl types accepted by Coana's reachability `--purl-types` gate
|
|
6512
|
+
// (@coana-tech/cli `getAdvisoryEcosystemFromPurlType`), narrower than
|
|
6513
|
+
// ALL_ECOSYSTEMS. Values outside this set are rejected by the engine at scan
|
|
6514
|
+
// time, so we validate up front. Keep in sync when bumping @coana-tech/cli.
|
|
6515
|
+
const REACHABILITY_SUPPORTED_ECOSYSTEMS = ['cargo', 'composer', 'gem', 'golang', 'maven', constants.NPM, 'nuget', 'pypi'];
|
|
6223
6516
|
function getEcosystemChoicesForMeow() {
|
|
6224
6517
|
return [...ALL_ECOSYSTEMS];
|
|
6225
6518
|
}
|
|
6519
|
+
function getReachabilityEcosystemChoices() {
|
|
6520
|
+
return [...REACHABILITY_SUPPORTED_ECOSYSTEMS];
|
|
6521
|
+
}
|
|
6522
|
+
function parseReachEcosystems(raw) {
|
|
6523
|
+
const choices = getReachabilityEcosystemChoices();
|
|
6524
|
+
const result = [];
|
|
6525
|
+
for (const ecosystem of raw) {
|
|
6526
|
+
if (!choices.includes(ecosystem)) {
|
|
6527
|
+
throw new InputError(`Invalid ecosystem: "${ecosystem}". Valid values are: ${arrays.joinAnd(choices)}`);
|
|
6528
|
+
}
|
|
6529
|
+
result.push(ecosystem);
|
|
6530
|
+
}
|
|
6531
|
+
return result;
|
|
6532
|
+
}
|
|
6226
6533
|
|
|
6227
6534
|
/**
|
|
6228
6535
|
* Package manager identifiers accepted by Coana's --package-managers filter.
|
|
@@ -6401,7 +6708,7 @@ function getNpmRequire() {
|
|
|
6401
6708
|
if (_npmRequire === undefined) {
|
|
6402
6709
|
const npmDirPath = getNpmDirPath();
|
|
6403
6710
|
const npmNmPath = path.join(npmDirPath, `${constants.NODE_MODULES}/npm`);
|
|
6404
|
-
_npmRequire = require$$
|
|
6711
|
+
_npmRequire = require$$1.createRequire(path.join(fs.existsSync(npmNmPath) ? npmNmPath : npmDirPath, '<dummy-basename>'));
|
|
6405
6712
|
}
|
|
6406
6713
|
return _npmRequire;
|
|
6407
6714
|
}
|
|
@@ -6453,7 +6760,7 @@ function shadowNpmInstall(options) {
|
|
|
6453
6760
|
__proto__: null,
|
|
6454
6761
|
...options
|
|
6455
6762
|
};
|
|
6456
|
-
const useDebug =
|
|
6763
|
+
const useDebug = debug$2.isDebug('stdio');
|
|
6457
6764
|
const terminatorPos = args.indexOf('--');
|
|
6458
6765
|
const rawBinArgs = terminatorPos === -1 ? args : args.slice(0, terminatorPos);
|
|
6459
6766
|
const binArgs = rawBinArgs.filter(a => !agent.isNpmAuditFlag(a) && !agent.isNpmFundFlag(a) && !agent.isNpmProgressFlag(a));
|
|
@@ -6461,12 +6768,12 @@ function shadowNpmInstall(options) {
|
|
|
6461
6768
|
const progressArg = rawBinArgs.findLast(agent.isNpmProgressFlag) !== '--no-progress';
|
|
6462
6769
|
const isSilent = !useDebug && !binArgs.some(agent.isNpmLoglevelFlag);
|
|
6463
6770
|
const logLevelArgs = isSilent ? [constants.FLAG_LOGLEVEL, 'silent'] : [];
|
|
6464
|
-
const useIpc =
|
|
6771
|
+
const useIpc = objects.isObject(ipc);
|
|
6465
6772
|
|
|
6466
6773
|
// Include 'ipc' in the spawnOpts.stdio when an options.ipc object is provided.
|
|
6467
6774
|
// See https://github.com/nodejs/node/blob/v23.6.0/lib/child_process.js#L161-L166
|
|
6468
6775
|
// and https://github.com/nodejs/node/blob/v23.6.0/lib/internal/child_process.js#L238.
|
|
6469
|
-
let stdio =
|
|
6776
|
+
let stdio = objects.getOwn(spawnOpts, 'stdio');
|
|
6470
6777
|
if (typeof stdio === 'string') {
|
|
6471
6778
|
stdio = useIpc ? [stdio, stdio, stdio, 'ipc'] : [stdio, stdio, stdio];
|
|
6472
6779
|
} else if (Array.isArray(stdio)) {
|
|
@@ -6488,7 +6795,7 @@ function shadowNpmInstall(options) {
|
|
|
6488
6795
|
env: {
|
|
6489
6796
|
...process.env,
|
|
6490
6797
|
...constants.default.processEnv,
|
|
6491
|
-
...
|
|
6798
|
+
...objects.getOwn(spawnOpts, 'env')
|
|
6492
6799
|
},
|
|
6493
6800
|
spinner,
|
|
6494
6801
|
stdio
|
|
@@ -6569,7 +6876,7 @@ function runAgentInstall(pkgEnvDetails, options) {
|
|
|
6569
6876
|
CI: '1'
|
|
6570
6877
|
} : {}),
|
|
6571
6878
|
NODE_OPTIONS: cmdFlagsToString([...(skipNodeHardenFlags ? [] : constants.default.nodeHardenFlags), ...constants.default.nodeNoWarningsFlags]),
|
|
6572
|
-
...
|
|
6879
|
+
...objects.getOwn(spawnOpts, 'env')
|
|
6573
6880
|
}
|
|
6574
6881
|
});
|
|
6575
6882
|
}
|
|
@@ -6751,7 +7058,7 @@ async function getAgentExecPath(agent) {
|
|
|
6751
7058
|
async function getAgentVersion(agent, agentExecPath, cwd) {
|
|
6752
7059
|
let result;
|
|
6753
7060
|
const quotedCmd = `\`${agent} ${constants.FLAG_VERSION}\``;
|
|
6754
|
-
|
|
7061
|
+
debug$2.debugFn('stdio', `spawn: ${quotedCmd}`);
|
|
6755
7062
|
try {
|
|
6756
7063
|
let stdout;
|
|
6757
7064
|
|
|
@@ -6767,8 +7074,8 @@ async function getAgentVersion(agent, agentExecPath, cwd) {
|
|
|
6767
7074
|
shouldRunWithNode = resolved;
|
|
6768
7075
|
}
|
|
6769
7076
|
} catch (e) {
|
|
6770
|
-
|
|
6771
|
-
|
|
7077
|
+
debug$2.debugFn('warn', `Failed to resolve bin path for ${agentExecPath}, falling back to direct spawn.`);
|
|
7078
|
+
debug$2.debugDir('error', e);
|
|
6772
7079
|
}
|
|
6773
7080
|
}
|
|
6774
7081
|
if (shouldRunWithNode) {
|
|
@@ -6790,11 +7097,11 @@ async function getAgentVersion(agent, agentExecPath, cwd) {
|
|
|
6790
7097
|
// and tildes (~).
|
|
6791
7098
|
vendor.semverExports.coerce(stdout) ?? undefined;
|
|
6792
7099
|
} catch (e) {
|
|
6793
|
-
|
|
6794
|
-
|
|
7100
|
+
debug$2.debugFn('error', `Package manager command failed: ${quotedCmd}`);
|
|
7101
|
+
debug$2.debugDir('inspect', {
|
|
6795
7102
|
cmd: quotedCmd
|
|
6796
7103
|
});
|
|
6797
|
-
|
|
7104
|
+
debug$2.debugDir('error', e);
|
|
6798
7105
|
}
|
|
6799
7106
|
return result;
|
|
6800
7107
|
}
|
|
@@ -7023,6 +7330,20 @@ async function detectAndValidatePackageEnvironment(cwd, options) {
|
|
|
7023
7330
|
};
|
|
7024
7331
|
}
|
|
7025
7332
|
|
|
7333
|
+
// Check the public npm registry for a newer socket release.
|
|
7334
|
+
async function runSelfUpdateCheck() {
|
|
7335
|
+
await vendor.updater({
|
|
7336
|
+
name: constants.default.SOCKET_CLI_BIN_NAME,
|
|
7337
|
+
registryUrl: 'https://registry.npmjs.org/',
|
|
7338
|
+
ttl: 86_400_000 /* 24 hours in milliseconds */,
|
|
7339
|
+
version: constants.default.ENV.INLINED_SOCKET_CLI_VERSION,
|
|
7340
|
+
logCallback: (name, version, latest) => {
|
|
7341
|
+
logger.logger.log(`\n\nš¦ Update available for ${vendor.yoctocolorsCjsExports.cyan(name)}: ${vendor.yoctocolorsCjsExports.gray(version)} ā ${vendor.yoctocolorsCjsExports.green(latest)}`);
|
|
7342
|
+
logger.logger.log(`š ${socketPackageLink('npm', name, `files/${latest}/CHANGELOG.md`, 'View changelog')}`);
|
|
7343
|
+
}
|
|
7344
|
+
});
|
|
7345
|
+
}
|
|
7346
|
+
|
|
7026
7347
|
/**
|
|
7027
7348
|
* Temporary package executor detection utilities for Socket CLI.
|
|
7028
7349
|
* Identifies and handles temporary execution contexts.
|
|
@@ -7309,7 +7630,7 @@ function toFilterConfig(obj) {
|
|
|
7309
7630
|
const normalized = {
|
|
7310
7631
|
__proto__: null
|
|
7311
7632
|
};
|
|
7312
|
-
const keys =
|
|
7633
|
+
const keys = objects.isObject(obj) ? Object.keys(obj) : [];
|
|
7313
7634
|
for (const key of keys) {
|
|
7314
7635
|
const value = obj[key];
|
|
7315
7636
|
if (typeof value === 'boolean' || Array.isArray(value)) {
|
|
@@ -7362,7 +7683,7 @@ function parsePnpmLockfile(lockfileContent) {
|
|
|
7362
7683
|
result = vendor.jsYaml.load(strings.stripBom(lockfileContent));
|
|
7363
7684
|
} catch {}
|
|
7364
7685
|
}
|
|
7365
|
-
return
|
|
7686
|
+
return objects.isObjectObject(result) ? result : null;
|
|
7366
7687
|
}
|
|
7367
7688
|
async function readPnpmLockfile(lockfilePath) {
|
|
7368
7689
|
return fs.existsSync(lockfilePath) ? await fs$1.readFileUtf8(lockfilePath) : undefined;
|
|
@@ -7463,7 +7784,7 @@ class ColorOrMarkdown {
|
|
|
7463
7784
|
}
|
|
7464
7785
|
}
|
|
7465
7786
|
|
|
7466
|
-
const require$1 = require$$
|
|
7787
|
+
const require$1 = require$$1.createRequire((typeof document === 'undefined' ? require$$0$1.pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('utils.js', document.baseURI).href)));
|
|
7467
7788
|
let _translations;
|
|
7468
7789
|
function getTranslations() {
|
|
7469
7790
|
if (_translations === undefined) {
|
|
@@ -7573,8 +7894,13 @@ async function addArtifactToAlertsMap(artifact, alertsByPurl, options) {
|
|
|
7573
7894
|
blocked: true,
|
|
7574
7895
|
critical: true,
|
|
7575
7896
|
cve: true,
|
|
7576
|
-
...
|
|
7897
|
+
...objects.getOwn(options, 'filter')
|
|
7577
7898
|
});
|
|
7899
|
+
|
|
7900
|
+
// `issueRules` is a user-provided YAML map typed as
|
|
7901
|
+
// `{ [issueName: string]: boolean }`, so key by `string` here. A string
|
|
7902
|
+
// index signature also keeps the `enabledState[alert.type]` lookup below
|
|
7903
|
+
// well-typed regardless of how `alert.type` resolves.
|
|
7578
7904
|
const enabledState = {
|
|
7579
7905
|
__proto__: null,
|
|
7580
7906
|
...socketYml?.issueRules
|
|
@@ -7593,7 +7919,7 @@ async function addArtifactToAlertsMap(artifact, alertsByPurl, options) {
|
|
|
7593
7919
|
const fixableCve = fixType === ALERT_FIX_TYPE.cve;
|
|
7594
7920
|
const fixableUpgrade = fixType === ALERT_FIX_TYPE.upgrade;
|
|
7595
7921
|
const fixable = fixableCve || fixableUpgrade;
|
|
7596
|
-
const upgradable = fixableUpgrade && !
|
|
7922
|
+
const upgradable = fixableUpgrade && !objects.hasOwn(overrides, name);
|
|
7597
7923
|
if (filterConfig.blocked && blocked || filterConfig.critical && critical || filterConfig.cve && cve || filterConfig.fixable && fixable || filterConfig.upgradable && upgradable) {
|
|
7598
7924
|
sockPkgAlerts.push({
|
|
7599
7925
|
name,
|
|
@@ -7867,7 +8193,7 @@ async function getAlertsMapFromPnpmLockfile(lockfile, options) {
|
|
|
7867
8193
|
}
|
|
7868
8194
|
async function getAlertsMapFromPurls(purls, options) {
|
|
7869
8195
|
const uniqPurls = arrays.arrayUnique(purls);
|
|
7870
|
-
|
|
8196
|
+
debug$2.debugDir('silly', {
|
|
7871
8197
|
purls: uniqPurls
|
|
7872
8198
|
});
|
|
7873
8199
|
let {
|
|
@@ -7882,7 +8208,7 @@ async function getAlertsMapFromPurls(purls, options) {
|
|
|
7882
8208
|
consolidate: false,
|
|
7883
8209
|
nothrow: false,
|
|
7884
8210
|
...options,
|
|
7885
|
-
filter: toFilterConfig(
|
|
8211
|
+
filter: toFilterConfig(objects.getOwn(options, 'filter'))
|
|
7886
8212
|
};
|
|
7887
8213
|
if (opts.onlyFixable) {
|
|
7888
8214
|
opts.filter.fixable = true;
|
|
@@ -7940,7 +8266,7 @@ async function getAlertsMapFromPurls(purls, options) {
|
|
|
7940
8266
|
} else {
|
|
7941
8267
|
spinner?.stop();
|
|
7942
8268
|
logger.logger.fail(`Received a ${batchResult.status} response from Socket API which we consider a permanent failure:`, batchResult.error, batchResult.cause ? `( ${batchResult.cause} )` : '');
|
|
7943
|
-
|
|
8269
|
+
debug$2.debugDir('inspect', {
|
|
7944
8270
|
batchResult
|
|
7945
8271
|
});
|
|
7946
8272
|
break;
|
|
@@ -8091,6 +8417,7 @@ function safeNpmSpecToPurl(pkgSpec) {
|
|
|
8091
8417
|
exports.ALL_PACKAGE_MANAGERS = ALL_PACKAGE_MANAGERS;
|
|
8092
8418
|
exports.AuthError = AuthError;
|
|
8093
8419
|
exports.COMPLETION_CMD_PREFIX = COMPLETION_CMD_PREFIX;
|
|
8420
|
+
exports.IGNORED_DIRS = IGNORED_DIRS;
|
|
8094
8421
|
exports.InputError = InputError;
|
|
8095
8422
|
exports.RangeStyles = RangeStyles;
|
|
8096
8423
|
exports.apiFetch = apiFetch;
|
|
@@ -8145,6 +8472,7 @@ exports.getOrgSlugs = getOrgSlugs;
|
|
|
8145
8472
|
exports.getOutputKind = getOutputKind;
|
|
8146
8473
|
exports.getPackageFilesForScan = getPackageFilesForScan;
|
|
8147
8474
|
exports.getPublicApiToken = getPublicApiToken;
|
|
8475
|
+
exports.getReachabilityEcosystemChoices = getReachabilityEcosystemChoices;
|
|
8148
8476
|
exports.getRepoInfo = getRepoInfo;
|
|
8149
8477
|
exports.getRepoName = getRepoName;
|
|
8150
8478
|
exports.getRepoOwner = getRepoOwner;
|
|
@@ -8191,13 +8519,16 @@ exports.meowOrExit = meowOrExit;
|
|
|
8191
8519
|
exports.meowWithSubcommands = meowWithSubcommands;
|
|
8192
8520
|
exports.msAtHome = msAtHome;
|
|
8193
8521
|
exports.parsePnpmLockfile = parsePnpmLockfile;
|
|
8522
|
+
exports.parseReachEcosystems = parseReachEcosystems;
|
|
8194
8523
|
exports.queryApiSafeJson = queryApiSafeJson;
|
|
8195
8524
|
exports.queryApiSafeText = queryApiSafeText;
|
|
8525
|
+
exports.queryApiSafeTextWithStatus = queryApiSafeTextWithStatus;
|
|
8196
8526
|
exports.readOrDefaultSocketJson = readOrDefaultSocketJson;
|
|
8197
8527
|
exports.readOrDefaultSocketJsonUp = readOrDefaultSocketJsonUp;
|
|
8198
8528
|
exports.readPnpmLockfile = readPnpmLockfile;
|
|
8199
8529
|
exports.readSocketJsonSync = readSocketJsonSync;
|
|
8200
8530
|
exports.runAgentInstall = runAgentInstall;
|
|
8531
|
+
exports.runSelfUpdateCheck = runSelfUpdateCheck;
|
|
8201
8532
|
exports.safeNpa = safeNpa$1;
|
|
8202
8533
|
exports.safeNpmSpecToPurl = safeNpmSpecToPurl;
|
|
8203
8534
|
exports.sendApiRequest = sendApiRequest;
|
|
@@ -8208,7 +8539,6 @@ exports.setupTelemetryExitHandlers = setupTelemetryExitHandlers;
|
|
|
8208
8539
|
exports.socketDashboardLink = socketDashboardLink;
|
|
8209
8540
|
exports.socketDevLink = socketDevLink;
|
|
8210
8541
|
exports.socketDocsLink = socketDocsLink;
|
|
8211
|
-
exports.socketPackageLink = socketPackageLink;
|
|
8212
8542
|
exports.spawnCdxgenDlx = spawnCdxgenDlx;
|
|
8213
8543
|
exports.spawnCoanaDlx = spawnCoanaDlx;
|
|
8214
8544
|
exports.spawnSynpDlx = spawnSynpDlx;
|
|
@@ -8224,6 +8554,7 @@ exports.trackSubprocessStart = trackSubprocessStart;
|
|
|
8224
8554
|
exports.updateConfigValue = updateConfigValue;
|
|
8225
8555
|
exports.walkNestedMap = walkNestedMap;
|
|
8226
8556
|
exports.webLink = webLink;
|
|
8557
|
+
exports.withTmpDir = withTmpDir;
|
|
8227
8558
|
exports.writeSocketJson = writeSocketJson;
|
|
8228
|
-
//# debugId=
|
|
8559
|
+
//# debugId=42fc0b13-4cfc-491d-a46f-94274b113cbc
|
|
8229
8560
|
//# sourceMappingURL=utils.js.map
|