@socketsecurity/cli-with-sentry 1.1.97 → 1.1.98
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 +5 -0
- package/dist/cli.js +49 -17
- package/dist/cli.js.map +1 -1
- package/dist/constants.js +3 -3
- package/dist/constants.js.map +1 -1
- package/dist/tsconfig.dts.tsbuildinfo +1 -1
- package/dist/types/commands/manifest/bazel/extract_bazel_to_maven.d.mts.map +1 -1
- package/dist/types/commands/scan/handle-create-new-scan.d.mts.map +1 -1
- package/dist/types/utils/api.d.mts +5 -3
- package/dist/types/utils/api.d.mts.map +1 -1
- package/dist/types/utils/coana.d.mts +35 -0
- package/dist/types/utils/coana.d.mts.map +1 -1
- package/dist/utils.js +131 -28
- package/dist/utils.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extract_bazel_to_maven.d.mts","sourceRoot":"","sources":["../../../../../src/commands/manifest/bazel/extract_bazel_to_maven.mts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAGjE,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,eAAe,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;IACvB,GAAG,EAAE,MAAM,CAAA;IACX,gEAAgE;IAChE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB,GAAG,EAAE,MAAM,CAAA;IACX,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,EAAE,EAAE,OAAO,CAAA;CACZ,CAAA;AAiBD,KAAK,uBAAuB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE;YAAE,GAAG,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACzE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;CACxC,CAAA;AA2DD,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,iBAAiB,EAAE,GAC7B,uBAAuB,CAqEzB;
|
|
1
|
+
{"version":3,"file":"extract_bazel_to_maven.d.mts","sourceRoot":"","sources":["../../../../../src/commands/manifest/bazel/extract_bazel_to_maven.mts"],"names":[],"mappings":"AAiCA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAGjE,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,eAAe,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;IACvB,GAAG,EAAE,MAAM,CAAA;IACX,gEAAgE;IAChE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB,GAAG,EAAE,MAAM,CAAA;IACX,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACjC,EAAE,EAAE,OAAO,CAAA;CACZ,CAAA;AAiBD,KAAK,uBAAuB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,OAAO,EAAE;YAAE,GAAG,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACzE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;CACxC,CAAA;AA2DD,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,iBAAiB,EAAE,GAC7B,uBAAuB,CAqEzB;AA6HD,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,kBAAkB,CAAC,CA6J7B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handle-create-new-scan.d.mts","sourceRoot":"","sources":["../../../../src/commands/scan/handle-create-new-scan.mts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"handle-create-new-scan.d.mts","sourceRoot":"","sources":["../../../../src/commands/scan/handle-create-new-scan.mts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAA;AAC9E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sCAAsC,CAAA;AAqCjE,MAAM,MAAM,yBAAyB,GAAG;IACtC,YAAY,EAAE,OAAO,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,aAAa,EAAE,OAAO,CAAA;IACtB,WAAW,EAAE,OAAO,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,OAAO,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,UAAU,CAAA;IACtB,KAAK,EAAE,KAAK,CACV,mBAAmB,GAAG;QACpB,uBAAuB,EAAE,OAAO,CAAA;KACjC,CACF,CAAA;IACD,QAAQ,EAAE,OAAO,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,OAAO,CAAA;IACf,WAAW,EAAE,YAAY,CAAA;IACzB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,GAAG,EAAE,OAAO,CAAA;IACZ,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAC/B,CAAA;AAED,wBAAsB,mBAAmB,CAAC,EACxC,YAAY,EACZ,UAAU,EACV,UAAU,EACV,aAAa,EACb,UAAU,EACV,GAAG,EACH,aAAa,EACb,WAAW,EACX,OAAO,EACP,UAAU,EACV,WAAW,EACX,WAAW,EACX,KAAK,EACL,QAAQ,EACR,QAAQ,EACR,MAAM,EACN,WAAW,EACX,OAAO,EACP,GAAG,EACH,SAAS,EACV,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiP3C"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { CResult } from '../types.mts';
|
|
2
2
|
import type { Spinner } from '@socketsecurity/registry/lib/spinner';
|
|
3
3
|
import type { SocketSdkOperations, SocketSdkResult, SocketSdkSuccessResult } from '@socketsecurity/sdk';
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
4
|
+
// All outbound API requests use node:https.request rather than global fetch.
|
|
5
|
+
// This ensures no body timeout is applied — large streaming ND-JSON responses
|
|
6
|
+
// (e.g. full scan results) can transfer without a hard deadline. When
|
|
7
|
+
// SSL_CERT_FILE is configured, a custom HttpsAgent carrying the extra CA
|
|
8
|
+
// certificates is passed; otherwise the default agent is used.
|
|
7
9
|
export type ApiFetchInit = {
|
|
8
10
|
body?: string | undefined;
|
|
9
11
|
headers?: Record<string, string> | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.mts","sourceRoot":"","sources":["../../../src/utils/api.mts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api.d.mts","sourceRoot":"","sources":["../../../src/utils/api.mts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,38 @@
|
|
|
1
|
+
export type CompressedScanPaths = {
|
|
2
|
+
paths: string[];
|
|
3
|
+
cleanup: () => Promise<void>;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* For each `.socket.facts.json` in `scanPaths`, stream-brotli-compress a
|
|
7
|
+
* sibling `.socket.facts.json.br` next to the original file and swap its
|
|
8
|
+
* path in. Other paths pass through unchanged. Missing files also pass
|
|
9
|
+
* through unchanged (the upload will fail downstream with the same error
|
|
10
|
+
* it would have).
|
|
11
|
+
*
|
|
12
|
+
* Streaming + worker-thread compression keeps the event loop responsive:
|
|
13
|
+
* default brotli quality (11) on a 60+MB facts file takes multiple seconds
|
|
14
|
+
* of CPU, which would otherwise freeze the spinner / signal handlers /
|
|
15
|
+
* any concurrent work.
|
|
16
|
+
*
|
|
17
|
+
* The `.br` lives next to the source rather than under the OS temp dir
|
|
18
|
+
* because depscan's multipart ingest (`addStreamEntry`) rejects entries
|
|
19
|
+
* whose names contain `..` traversal segments. The SDK computes the
|
|
20
|
+
* multipart entry name via `path.relative(cwd, brPath)`, so an OS-tmpdir
|
|
21
|
+
* temp path turns into `../../../var/folders/...` and gets dropped as
|
|
22
|
+
* `unmatchedFiles`. Sibling-write keeps the relative path inside cwd, and
|
|
23
|
+
* keeps the directory shape symmetric with the plain `.socket.facts.json`
|
|
24
|
+
* upload (depscan strips only the `.br` suffix at ingest, so
|
|
25
|
+
* `<dir>/.socket.facts.json.br` and `<dir>/.socket.facts.json` resolve to
|
|
26
|
+
* the same storage path).
|
|
27
|
+
*
|
|
28
|
+
* Concurrent scans against the same source directory are already racy on
|
|
29
|
+
* `.socket.facts.json` itself (coana writes to a single path), so the
|
|
30
|
+
* sibling `.br` doesn't introduce a new race.
|
|
31
|
+
*
|
|
32
|
+
* Caller MUST `await cleanup()` (typically in a `finally` block) once the
|
|
33
|
+
* upload completes — successful or not — to remove the sibling files.
|
|
34
|
+
*/
|
|
35
|
+
export declare function compressSocketFactsForUpload(scanPaths: string[]): Promise<CompressedScanPaths>;
|
|
1
36
|
export type ReachabilityError = {
|
|
2
37
|
componentName: string;
|
|
3
38
|
componentVersion: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coana.d.mts","sourceRoot":"","sources":["../../../src/utils/coana.mts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"coana.d.mts","sourceRoot":"","sources":["../../../src/utils/coana.mts"],"names":[],"mappings":"AA8BA,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC7B,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAsB,4BAA4B,CAChD,SAAS,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,mBAAmB,CAAC,CAgD9B;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,aAAa,EAAE,MAAM,CAAA;IACrB,gBAAgB,EAAE,MAAM,CAAA;IACxB,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,EAAE,MAAM,CAAA;CACvB,CAAA;AAED,wBAAgB,yBAAyB,CACvC,eAAe,EAAE,MAAM,GACtB,iBAAiB,EAAE,CA0CrB;AAED,wBAAgB,8BAA8B,CAC5C,eAAe,EAAE,MAAM,GACtB,MAAM,GAAG,SAAS,CAQpB"}
|
package/dist/utils.js
CHANGED
|
@@ -16,10 +16,14 @@ var path = require('node:path');
|
|
|
16
16
|
var regexps = require('../external/@socketsecurity/registry/lib/regexps');
|
|
17
17
|
var prompts = require('../external/@socketsecurity/registry/lib/prompts');
|
|
18
18
|
var spawn = require('../external/@socketsecurity/registry/lib/spawn');
|
|
19
|
+
var fs = require('node:fs');
|
|
20
|
+
var fs$2 = require('node:fs/promises');
|
|
21
|
+
var promises$1 = require('node:stream/promises');
|
|
22
|
+
var node_zlib = require('node:zlib');
|
|
19
23
|
var fs$1 = require('../external/@socketsecurity/registry/lib/fs');
|
|
20
24
|
var require$$5 = require('node:module');
|
|
21
25
|
var require$$3 = require('node:https');
|
|
22
|
-
var
|
|
26
|
+
var web = require('node:stream/web');
|
|
23
27
|
var require$$13 = require('../external/@socketsecurity/registry/lib/url');
|
|
24
28
|
var agent = require('../external/@socketsecurity/registry/lib/agent');
|
|
25
29
|
var bin = require('../external/@socketsecurity/registry/lib/bin');
|
|
@@ -2051,9 +2055,11 @@ function getHttpsAgent() {
|
|
|
2051
2055
|
return _httpsAgent;
|
|
2052
2056
|
}
|
|
2053
2057
|
|
|
2054
|
-
//
|
|
2055
|
-
//
|
|
2056
|
-
//
|
|
2058
|
+
// All outbound API requests use node:https.request rather than global fetch.
|
|
2059
|
+
// This ensures no body timeout is applied — large streaming ND-JSON responses
|
|
2060
|
+
// (e.g. full scan results) can transfer without a hard deadline. When
|
|
2061
|
+
// SSL_CERT_FILE is configured, a custom HttpsAgent carrying the extra CA
|
|
2062
|
+
// certificates is passed; otherwise the default agent is used.
|
|
2057
2063
|
|
|
2058
2064
|
// Internal httpsRequest-based fetch with redirect support.
|
|
2059
2065
|
function _httpsRequestFetch(url, init, agent, redirectCount) {
|
|
@@ -2109,27 +2115,42 @@ function _httpsRequestFetch(url, init, agent, redirectCount) {
|
|
|
2109
2115
|
}, agent, redirectCount + 1));
|
|
2110
2116
|
return;
|
|
2111
2117
|
}
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
responseHeaders.
|
|
2120
|
-
} else if (Array.isArray(value)) {
|
|
2121
|
-
for (const v of value) {
|
|
2122
|
-
responseHeaders.append(key, v);
|
|
2123
|
-
}
|
|
2118
|
+
// Build response headers immediately on receipt.
|
|
2119
|
+
const responseHeaders = new Headers();
|
|
2120
|
+
for (const [key, value] of Object.entries(res.headers)) {
|
|
2121
|
+
if (typeof value === 'string') {
|
|
2122
|
+
responseHeaders.set(key, value);
|
|
2123
|
+
} else if (Array.isArray(value)) {
|
|
2124
|
+
for (const v of value) {
|
|
2125
|
+
responseHeaders.append(key, v);
|
|
2124
2126
|
}
|
|
2125
2127
|
}
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2128
|
+
}
|
|
2129
|
+
// Resolve with a streaming body as soon as headers are available,
|
|
2130
|
+
// matching fetch() semantics. Callers that pipe response.body (e.g.
|
|
2131
|
+
// streamDownloadWithFetch) receive a live ReadableStream rather than
|
|
2132
|
+
// a fully-buffered Buffer.
|
|
2133
|
+
const body = new web.ReadableStream({
|
|
2134
|
+
start(controller) {
|
|
2135
|
+
res.on('data', chunk => {
|
|
2136
|
+
controller.enqueue(chunk);
|
|
2137
|
+
});
|
|
2138
|
+
res.on('end', () => {
|
|
2139
|
+
controller.close();
|
|
2140
|
+
});
|
|
2141
|
+
res.on('error', err => {
|
|
2142
|
+
controller.error(err);
|
|
2143
|
+
});
|
|
2144
|
+
},
|
|
2145
|
+
cancel() {
|
|
2146
|
+
res.destroy();
|
|
2147
|
+
}
|
|
2131
2148
|
});
|
|
2132
|
-
|
|
2149
|
+
resolve(new Response(body, {
|
|
2150
|
+
status: statusCode ?? 0,
|
|
2151
|
+
statusText: res.statusMessage ?? '',
|
|
2152
|
+
headers: responseHeaders
|
|
2153
|
+
}));
|
|
2133
2154
|
});
|
|
2134
2155
|
if (init.body) {
|
|
2135
2156
|
req.write(init.body);
|
|
@@ -2139,11 +2160,7 @@ function _httpsRequestFetch(url, init, agent, redirectCount) {
|
|
|
2139
2160
|
});
|
|
2140
2161
|
}
|
|
2141
2162
|
async function apiFetch(url, init = {}) {
|
|
2142
|
-
|
|
2143
|
-
if (!agent) {
|
|
2144
|
-
return await fetch(url, init);
|
|
2145
|
-
}
|
|
2146
|
-
return await _httpsRequestFetch(url, init, agent, 0);
|
|
2163
|
+
return await _httpsRequestFetch(url, init, getHttpsAgent(), 0);
|
|
2147
2164
|
}
|
|
2148
2165
|
/**
|
|
2149
2166
|
* Get command requirements from requirements.json based on command path.
|
|
@@ -4724,6 +4741,11 @@ function* walkNestedMap(map, keys = []) {
|
|
|
4724
4741
|
* Manages reachability analysis via Coana tech CLI.
|
|
4725
4742
|
*
|
|
4726
4743
|
* Key Functions:
|
|
4744
|
+
* - compressSocketFactsForUpload: Brotli-compress any .socket.facts.json
|
|
4745
|
+
* entries in scanPaths just before upload, returning swapped paths plus a
|
|
4746
|
+
* cleanup callback. Coana keeps writing plain JSON; the on-the-wire form
|
|
4747
|
+
* to depscan is brotli (api-v0 decodes at the multipart boundary).
|
|
4748
|
+
* - extractReachabilityErrors: Extract per-component reachability errors
|
|
4727
4749
|
* - extractTier1ReachabilityScanId: Extract scan ID from socket facts file
|
|
4728
4750
|
*
|
|
4729
4751
|
* Integration:
|
|
@@ -4732,6 +4754,86 @@ function* walkNestedMap(map, keys = []) {
|
|
|
4732
4754
|
* - Extracts tier 1 reachability scan identifiers
|
|
4733
4755
|
*/
|
|
4734
4756
|
|
|
4757
|
+
const {
|
|
4758
|
+
DOT_SOCKET_DOT_FACTS_JSON
|
|
4759
|
+
} = constants.default;
|
|
4760
|
+
/**
|
|
4761
|
+
* For each `.socket.facts.json` in `scanPaths`, stream-brotli-compress a
|
|
4762
|
+
* sibling `.socket.facts.json.br` next to the original file and swap its
|
|
4763
|
+
* path in. Other paths pass through unchanged. Missing files also pass
|
|
4764
|
+
* through unchanged (the upload will fail downstream with the same error
|
|
4765
|
+
* it would have).
|
|
4766
|
+
*
|
|
4767
|
+
* Streaming + worker-thread compression keeps the event loop responsive:
|
|
4768
|
+
* default brotli quality (11) on a 60+MB facts file takes multiple seconds
|
|
4769
|
+
* of CPU, which would otherwise freeze the spinner / signal handlers /
|
|
4770
|
+
* any concurrent work.
|
|
4771
|
+
*
|
|
4772
|
+
* The `.br` lives next to the source rather than under the OS temp dir
|
|
4773
|
+
* because depscan's multipart ingest (`addStreamEntry`) rejects entries
|
|
4774
|
+
* whose names contain `..` traversal segments. The SDK computes the
|
|
4775
|
+
* multipart entry name via `path.relative(cwd, brPath)`, so an OS-tmpdir
|
|
4776
|
+
* temp path turns into `../../../var/folders/...` and gets dropped as
|
|
4777
|
+
* `unmatchedFiles`. Sibling-write keeps the relative path inside cwd, and
|
|
4778
|
+
* keeps the directory shape symmetric with the plain `.socket.facts.json`
|
|
4779
|
+
* upload (depscan strips only the `.br` suffix at ingest, so
|
|
4780
|
+
* `<dir>/.socket.facts.json.br` and `<dir>/.socket.facts.json` resolve to
|
|
4781
|
+
* the same storage path).
|
|
4782
|
+
*
|
|
4783
|
+
* Concurrent scans against the same source directory are already racy on
|
|
4784
|
+
* `.socket.facts.json` itself (coana writes to a single path), so the
|
|
4785
|
+
* sibling `.br` doesn't introduce a new race.
|
|
4786
|
+
*
|
|
4787
|
+
* Caller MUST `await cleanup()` (typically in a `finally` block) once the
|
|
4788
|
+
* upload completes — successful or not — to remove the sibling files.
|
|
4789
|
+
*/
|
|
4790
|
+
async function compressSocketFactsForUpload(scanPaths) {
|
|
4791
|
+
const brPaths = [];
|
|
4792
|
+
const cleanup = async () => {
|
|
4793
|
+
const targets = brPaths.splice(0);
|
|
4794
|
+
// `recursive: true` defends against the (defensive) case where a sibling
|
|
4795
|
+
// path was somehow created as a directory — `rm` would otherwise throw
|
|
4796
|
+
// on the first such entry and skip the rest. `force: true` no-ops on
|
|
4797
|
+
// missing paths so the function stays idempotent.
|
|
4798
|
+
await Promise.all(targets.map(t => fs$2.rm(t, {
|
|
4799
|
+
recursive: true,
|
|
4800
|
+
force: true
|
|
4801
|
+
})));
|
|
4802
|
+
};
|
|
4803
|
+
// Use `allSettled` (not `all`) so a failure in one entry doesn't leak the
|
|
4804
|
+
// others' in-flight pipelines past our `catch`. If we used `all`, the
|
|
4805
|
+
// first rejection would bubble out while sibling pipelines were still
|
|
4806
|
+
// writing bytes — `cleanup()` would race with those writes and could
|
|
4807
|
+
// remove a `.br` only to have it re-created after we returned.
|
|
4808
|
+
const results = await Promise.allSettled(scanPaths.map(async p => {
|
|
4809
|
+
if (path.basename(p) !== DOT_SOCKET_DOT_FACTS_JSON) {
|
|
4810
|
+
return p;
|
|
4811
|
+
}
|
|
4812
|
+
if (!fs.existsSync(p)) {
|
|
4813
|
+
return p;
|
|
4814
|
+
}
|
|
4815
|
+
const brPath = `${p}.br`;
|
|
4816
|
+
// Track the sibling path BEFORE the pipeline starts so a
|
|
4817
|
+
// partially-written `.br` is removed even if the pipeline rejects.
|
|
4818
|
+
// `rm({ force: true })` no-ops on missing files, so tracking before
|
|
4819
|
+
// creation is safe.
|
|
4820
|
+
brPaths.push(brPath);
|
|
4821
|
+
await promises$1.pipeline(fs.createReadStream(p), node_zlib.createBrotliCompress(), fs.createWriteStream(brPath));
|
|
4822
|
+
return brPath;
|
|
4823
|
+
}));
|
|
4824
|
+
const failure = results.find(r => r.status === 'rejected');
|
|
4825
|
+
if (failure) {
|
|
4826
|
+
// All pipelines have settled, so cleanup() can safely remove every
|
|
4827
|
+
// `.br` we tracked (succeeded or partial) without racing live writes.
|
|
4828
|
+
await cleanup();
|
|
4829
|
+
throw failure.reason;
|
|
4830
|
+
}
|
|
4831
|
+
const paths = results.map(r => r.value);
|
|
4832
|
+
return {
|
|
4833
|
+
paths,
|
|
4834
|
+
cleanup
|
|
4835
|
+
};
|
|
4836
|
+
}
|
|
4735
4837
|
function extractReachabilityErrors(socketFactsFile) {
|
|
4736
4838
|
const json = fs$1.readJsonSync(socketFactsFile, {
|
|
4737
4839
|
throws: false
|
|
@@ -7822,6 +7924,7 @@ exports.checkCommandInput = checkCommandInput;
|
|
|
7822
7924
|
exports.cmdFlagValueToArray = cmdFlagValueToArray;
|
|
7823
7925
|
exports.cmdFlagsToString = cmdFlagsToString;
|
|
7824
7926
|
exports.cmdPrefixMessage = cmdPrefixMessage;
|
|
7927
|
+
exports.compressSocketFactsForUpload = compressSocketFactsForUpload;
|
|
7825
7928
|
exports.convertCveToGhsa = convertCveToGhsa;
|
|
7826
7929
|
exports.convertPurlToGhsas = convertPurlToGhsas;
|
|
7827
7930
|
exports.createEnum = createEnum;
|
|
@@ -7946,5 +8049,5 @@ exports.updateConfigValue = updateConfigValue;
|
|
|
7946
8049
|
exports.walkNestedMap = walkNestedMap;
|
|
7947
8050
|
exports.webLink = webLink;
|
|
7948
8051
|
exports.writeSocketJson = writeSocketJson;
|
|
7949
|
-
//# debugId=
|
|
8052
|
+
//# debugId=e3aec7ef-9385-4b5c-be2e-ba11a8c6f580
|
|
7950
8053
|
//# sourceMappingURL=utils.js.map
|