@socketsecurity/lib 6.0.7 → 6.0.8
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 +20 -0
- package/README.md +1 -1
- package/dist/ai/agent-context.d.mts +103 -0
- package/dist/ai/agent-context.js +157 -0
- package/dist/ai/backends.d.mts +83 -0
- package/dist/ai/backends.js +173 -0
- package/dist/ai/credentials.d.mts +49 -0
- package/dist/ai/credentials.js +82 -0
- package/dist/ai/discover.d.mts +4 -0
- package/dist/ai/discover.js +1 -1
- package/dist/ai/exec.d.mts +52 -0
- package/dist/ai/exec.js +92 -0
- package/dist/ai/http.d.mts +132 -0
- package/dist/ai/http.js +130 -0
- package/dist/ai/profiles.d.mts +41 -6
- package/dist/ai/profiles.js +52 -10
- package/dist/ai/route.d.mts +69 -0
- package/dist/ai/route.js +156 -0
- package/dist/ai/spawn.d.mts +10 -2
- package/dist/ai/spawn.js +55 -31
- package/dist/ai/subagent-status.d.mts +48 -0
- package/dist/ai/subagent-status.js +57 -0
- package/dist/ai/tier.d.mts +60 -0
- package/dist/ai/tier.js +53 -0
- package/dist/ai/types.d.mts +15 -2
- package/dist/ai/worktree.js +4 -0
- package/dist/archives/tar.js +1 -1
- package/dist/archives/zip.js +2 -2
- package/dist/argv/parse.d.ts +19 -2
- package/dist/argv/parse.js +1 -1
- package/dist/arrays/join.js +4 -0
- package/dist/bin/find.js +4 -4
- package/dist/bin/prim.cjs +3915 -3781
- package/dist/bin/resolve.js +1 -1
- package/dist/cache/ttl/store.js +1 -1
- package/dist/cli/check-primordials.d.ts +8 -3
- package/dist/cli/check-primordials.js +4 -4
- package/dist/compression/_internal.js +1 -1
- package/dist/compression/brotli.d.ts +1 -2
- package/dist/compression/brotli.js +6 -2
- package/dist/compression/gzip.js +6 -2
- package/dist/constants/packages.d.ts +3 -0
- package/dist/constants/packages.js +2 -1
- package/dist/constants/socket.d.ts +2 -6
- package/dist/constants/socket.js +12 -14
- package/dist/cover/code.js +2 -2
- package/dist/crypto/hash.d.ts +4 -1
- package/dist/crypto/hash.js +4 -1
- package/dist/debug/caller-info.js +1 -1
- package/dist/dlx/arborist.js +13 -3
- package/dist/dlx/binary-cache.js +1 -1
- package/dist/dlx/binary-resolution.js +1 -1
- package/dist/dlx/detect.d.ts +8 -0
- package/dist/dlx/firewall.d.ts +8 -0
- package/dist/dlx/firewall.js +1 -1
- package/dist/dlx/lockfile.js +4 -1
- package/dist/dlx/manifest.js +1 -1
- package/dist/dlx/package.js +4 -0
- package/dist/eco/cargo/parse-lockfile.d.ts +1 -2
- package/dist/eco/cargo/parse-lockfile.js +3 -3
- package/dist/eco/manifest/detect-format.js +1 -1
- package/dist/eco/npm/npm/parse-lockfile.d.ts +3 -4
- package/dist/eco/npm/npm/parse-lockfile.js +2 -2
- package/dist/eco/npm/parse-package-json.d.ts +11 -0
- package/dist/eco/npm/parse-package-json.js +1 -1
- package/dist/eco/npm/pnpm/parse-lockfile.d.ts +5 -3
- package/dist/eco/npm/pnpm/parse-lockfile.js +3 -3
- package/dist/eco/npm/yarnpkg/yarn/exec.js +1 -1
- package/dist/eco/npm/yarnpkg/yarn/parse-lockfile.d.ts +1 -2
- package/dist/eco/npm/yarnpkg/yarn/parse-lockfile.js +1 -1
- package/dist/env/proxy.js +1 -1
- package/dist/env/rewire.d.ts +1 -0
- package/dist/env/rewire.js +1 -1
- package/dist/env/socket.d.ts +7 -0
- package/dist/env/socket.js +10 -0
- package/dist/errors/predicates.js +1 -1
- package/dist/external/@npmcli/promise-spawn.js +3 -1
- package/dist/external/pico-pack.js +4 -2
- package/dist/external/which.js +3 -1
- package/dist/external-tools/bazel/asset-names.d.ts +1 -1
- package/dist/external-tools/bazel/asset-names.js +5 -2
- package/dist/external-tools/bazel/from-download.d.ts +1 -1
- package/dist/external-tools/bazel/from-download.js +5 -2
- package/dist/external-tools/bazel/resolve-bazel-version.js +4 -0
- package/dist/external-tools/bazel/resolve.d.ts +3 -3
- package/dist/external-tools/bazel/resolve.js +16 -8
- package/dist/external-tools/cdxgen/asset-names.d.ts +1 -1
- package/dist/external-tools/cdxgen/asset-names.js +5 -2
- package/dist/external-tools/cdxgen/from-download.d.ts +1 -1
- package/dist/external-tools/cdxgen/from-download.js +7 -4
- package/dist/external-tools/cdxgen/resolve.d.ts +3 -3
- package/dist/external-tools/cdxgen/resolve.js +16 -8
- package/dist/external-tools/from-download.d.ts +2 -2
- package/dist/external-tools/from-download.js +11 -5
- package/dist/external-tools/from-pip-venv.d.ts +1 -1
- package/dist/external-tools/from-pip-venv.js +12 -5
- package/dist/external-tools/janus/asset-names.d.ts +1 -1
- package/dist/external-tools/janus/asset-names.js +5 -2
- package/dist/external-tools/janus/from-download.d.ts +1 -1
- package/dist/external-tools/janus/from-download.js +5 -2
- package/dist/external-tools/janus/resolve.d.ts +3 -3
- package/dist/external-tools/janus/resolve.js +16 -8
- package/dist/external-tools/jre/asset-names.d.ts +1 -1
- package/dist/external-tools/jre/asset-names.js +5 -2
- package/dist/external-tools/jre/from-download.d.ts +1 -1
- package/dist/external-tools/jre/from-download.js +7 -4
- package/dist/external-tools/jre/from-java-home.js +2 -2
- package/dist/external-tools/jre/from-vfs.js +2 -2
- package/dist/external-tools/jre/resolve.d.ts +3 -3
- package/dist/external-tools/jre/resolve.js +16 -8
- package/dist/external-tools/manifest.d.ts +18 -0
- package/dist/external-tools/manifest.js +1 -1
- package/dist/external-tools/opengrep/asset-names.d.ts +1 -1
- package/dist/external-tools/opengrep/asset-names.js +5 -2
- package/dist/external-tools/opengrep/from-download.d.ts +1 -1
- package/dist/external-tools/opengrep/from-download.js +5 -2
- package/dist/external-tools/opengrep/resolve.d.ts +3 -3
- package/dist/external-tools/opengrep/resolve.js +16 -8
- package/dist/external-tools/python/asset-names.d.ts +1 -1
- package/dist/external-tools/python/asset-names.js +10 -3
- package/dist/external-tools/python/dlx.d.ts +3 -3
- package/dist/external-tools/python/dlx.js +20 -9
- package/dist/external-tools/python/from-download.d.ts +1 -1
- package/dist/external-tools/python/from-download.js +12 -5
- package/dist/external-tools/python/pin.js +6 -3
- package/dist/external-tools/python/pip-install.js +6 -3
- package/dist/external-tools/python/resolve.d.ts +3 -3
- package/dist/external-tools/python/resolve.js +19 -11
- package/dist/external-tools/sbt/asset-names.d.ts +1 -1
- package/dist/external-tools/sbt/asset-names.js +5 -2
- package/dist/external-tools/sbt/from-download.d.ts +1 -1
- package/dist/external-tools/sbt/from-download.js +5 -2
- package/dist/external-tools/sbt/resolve.d.ts +3 -3
- package/dist/external-tools/sbt/resolve.js +16 -8
- package/dist/external-tools/skillspector/from-dlx.d.ts +1 -1
- package/dist/external-tools/skillspector/from-dlx.js +10 -3
- package/dist/external-tools/skillspector/resolve.d.ts +2 -2
- package/dist/external-tools/skillspector/resolve.js +14 -6
- package/dist/external-tools/synp/asset-names.d.ts +1 -1
- package/dist/external-tools/synp/asset-names.js +6 -2
- package/dist/external-tools/synp/from-download.d.ts +1 -1
- package/dist/external-tools/synp/from-download.js +5 -2
- package/dist/external-tools/synp/resolve.d.ts +3 -3
- package/dist/external-tools/synp/resolve.js +16 -8
- package/dist/external-tools/trivy/asset-names.d.ts +1 -1
- package/dist/external-tools/trivy/asset-names.js +5 -2
- package/dist/external-tools/trivy/from-download.d.ts +1 -1
- package/dist/external-tools/trivy/from-download.js +7 -4
- package/dist/external-tools/trivy/resolve.d.ts +3 -3
- package/dist/external-tools/trivy/resolve.js +16 -8
- package/dist/external-tools/trufflehog/asset-names.d.ts +1 -1
- package/dist/external-tools/trufflehog/asset-names.js +5 -2
- package/dist/external-tools/trufflehog/from-download.d.ts +1 -1
- package/dist/external-tools/trufflehog/from-download.js +7 -4
- package/dist/external-tools/trufflehog/resolve.d.ts +3 -3
- package/dist/external-tools/trufflehog/resolve.js +16 -8
- package/dist/fs/allowed-dirs-cache.d.ts +27 -1
- package/dist/fs/allowed-dirs-cache.js +38 -3
- package/dist/fs/find.js +1 -1
- package/dist/fs/read-json-cache.d.ts +7 -0
- package/dist/fs/resolve-module.js +6 -2
- package/dist/fs/safe.js +1 -1
- package/dist/git/_internal.js +2 -2
- package/dist/git/repo.js +2 -4
- package/dist/git/staged.js +8 -0
- package/dist/git/tracked.d.ts +84 -0
- package/dist/git/tracked.js +163 -0
- package/dist/git/unstaged.js +8 -0
- package/dist/github/refs-graphql.js +4 -0
- package/dist/github/refs-rest.js +4 -0
- package/dist/github/refs.js +15 -10
- package/dist/globs/_internal.js +1 -1
- package/dist/globs/match.js +9 -1
- package/dist/globs/matcher.js +5 -1
- package/dist/http-request/browser.js +6 -2
- package/dist/http-request/{browser-fetch.d.ts → fetch/browser.d.ts} +2 -2
- package/dist/http-request/{browser-fetch.js → fetch/browser.js} +4 -4
- package/dist/http-request/headers.js +1 -1
- package/dist/http-request/request-attempt.js +2 -2
- package/dist/http-request/user-agent.js +1 -1
- package/dist/integrity.d.ts +10 -4
- package/dist/integrity.js +10 -4
- package/dist/json/edit.js +38 -30
- package/dist/json/format.js +1 -1
- package/dist/native-messaging/install.d.ts +1 -1
- package/dist/native-messaging/install.js +7 -4
- package/dist/native-messaging/rate-limit.d.ts +7 -0
- package/dist/native-messaging/rate-limit.js +4 -0
- package/dist/node/async-hooks.js +1 -1
- package/dist/node/child-process.js +1 -1
- package/dist/node/crypto.js +1 -1
- package/dist/node/events.js +1 -1
- package/dist/node/fs-promises.js +1 -1
- package/dist/node/fs.d.ts +22 -6
- package/dist/node/fs.js +16 -3
- package/dist/node/http.js +1 -1
- package/dist/node/https.js +1 -1
- package/dist/node/module.js +1 -1
- package/dist/node/os.d.ts +10 -2
- package/dist/node/os.js +11 -4
- package/dist/node/path.d.ts +11 -2
- package/dist/node/path.js +17 -4
- package/dist/node/timers-promises.js +1 -1
- package/dist/node/url.js +1 -1
- package/dist/node/util.js +1 -1
- package/dist/objects/getters.js +1 -1
- package/dist/objects/mutate.js +2 -2
- package/dist/objects/predicates.js +1 -1
- package/dist/packages/edit-class.d.ts +2 -3
- package/dist/packages/edit-class.js +41 -35
- package/dist/packages/exports.js +4 -4
- package/dist/packages/fetch.js +1 -1
- package/dist/packages/isolation.js +1 -1
- package/dist/packages/licenses.js +2 -2
- package/dist/packages/manifest.js +4 -4
- package/dist/packages/normalize.js +1 -1
- package/dist/packages/provenance.js +2 -2
- package/dist/packages/specs.js +1 -1
- package/dist/packages/tarball.js +4 -2
- package/dist/packages/types.d.ts +1 -2
- package/dist/paths/dirnames.d.ts +1 -0
- package/dist/paths/dirnames.js +2 -0
- package/dist/paths/resolve.js +14 -19
- package/dist/paths/rewire.d.ts +5 -0
- package/dist/paths/socket.d.ts +74 -111
- package/dist/paths/socket.js +99 -132
- package/dist/primordials/process.d.ts +88 -0
- package/dist/primordials/process.js +132 -0
- package/dist/primordials/uncurry.d.ts +1 -2
- package/dist/process/spawn/child.js +8 -2
- package/dist/process/spawn/errors.js +1 -1
- package/dist/regexps/spec.js +1 -1
- package/dist/releases/github-archives.js +1 -1
- package/dist/releases/github-listing.d.ts +1 -2
- package/dist/schema/types.d.ts +3 -4
- package/dist/schema/validate.js +1 -1
- package/dist/secrets/find.d.ts +2 -2
- package/dist/secrets/find.js +10 -4
- package/dist/secrets/keychain.d.ts +1 -1
- package/dist/secrets/linux.js +32 -44
- package/dist/secrets/macos.d.ts +1 -2
- package/dist/secrets/macos.js +20 -29
- package/dist/secrets/rc.d.ts +2 -2
- package/dist/secrets/rc.js +21 -13
- package/dist/secrets/socket-api-token.js +8 -0
- package/dist/secrets/windows.js +27 -33
- package/dist/shell/parse.d.ts +32 -0
- package/dist/shell/parse.js +60 -0
- package/dist/spinner/create-spinner-class.js +2 -2
- package/dist/spinner/spinner-internals.d.ts +1 -1
- package/dist/spinner/spinner-internals.js +9 -5
- package/dist/spinner/spinner.d.ts +4 -0
- package/dist/spinner/spinner.js +1 -1
- package/dist/stdio/progress.js +5 -1
- package/dist/stdio/prompts.d.ts +2 -2
- package/dist/stdio/prompts.js +1 -1
- package/dist/temporal/instant.js +2 -2
- package/dist/url/assert-safe.d.ts +29 -0
- package/dist/url/assert-safe.js +54 -0
- package/dist/url/predicates.d.ts +31 -1
- package/dist/url/predicates.js +42 -1
- package/dist/url/types.d.ts +4 -0
- package/package.json +177 -115
package/dist/secrets/rc.js
CHANGED
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
/* Socket Lib - Built with rolldown */
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
4
|
const require_runtime = require('../_virtual/_rolldown/runtime.js');
|
|
5
|
-
const require_primordials_string = require('../primordials/string.js');
|
|
6
|
-
const require_primordials_regexp = require('../primordials/regexp.js');
|
|
7
5
|
const require_primordials_object = require('../primordials/object.js');
|
|
8
6
|
const require_env_home = require('../env/home.js');
|
|
7
|
+
const require_primordials_string = require('../primordials/string.js');
|
|
8
|
+
const require_primordials_regexp = require('../primordials/regexp.js');
|
|
9
9
|
let node_fs = require("node:fs");
|
|
10
|
+
let node_process = require("node:process");
|
|
11
|
+
node_process = require_runtime.__toESM(node_process);
|
|
10
12
|
let node_path = require("node:path");
|
|
11
13
|
node_path = require_runtime.__toESM(node_path);
|
|
12
14
|
let node_os = require("node:os");
|
|
13
15
|
node_os = require_runtime.__toESM(node_os);
|
|
14
|
-
let node_process = require("node:process");
|
|
15
|
-
node_process = require_runtime.__toESM(node_process);
|
|
16
16
|
|
|
17
17
|
//#region src/secrets/rc.ts
|
|
18
18
|
/**
|
|
@@ -54,11 +54,15 @@ node_process = require_runtime.__toESM(node_process);
|
|
|
54
54
|
* non-interactive shells (Claude Code, IDE plugins, CI runners) skip .zshrc
|
|
55
55
|
* and would miss the export.
|
|
56
56
|
*/
|
|
57
|
-
function buildBlock(
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
57
|
+
function buildBlock(options) {
|
|
58
|
+
options = {
|
|
59
|
+
__proto__: null,
|
|
60
|
+
...options
|
|
61
|
+
};
|
|
62
|
+
const begin = `# BEGIN ${options.service} env (managed)`;
|
|
63
|
+
const end = `# END ${options.service} env (managed)`;
|
|
64
|
+
const noteLines = (options.notes ?? []).map((line) => `# ${line}`);
|
|
65
|
+
const exportLines = require_primordials_object.ObjectEntries(options.exports).map(([name, value]) => `export ${name}=${shellSingleQuote(value)}`);
|
|
62
66
|
const body = [...noteLines, ...exportLines].join("\n");
|
|
63
67
|
return {
|
|
64
68
|
begin,
|
|
@@ -134,23 +138,27 @@ function shellSingleQuote(value) {
|
|
|
134
138
|
* `shell` and `rcPath` override the auto-detected target — useful for chezmoi /
|
|
135
139
|
* dotfile-manager users or installers running under a non-default shell.
|
|
136
140
|
*/
|
|
137
|
-
function write(
|
|
141
|
+
function write(options) {
|
|
142
|
+
options = {
|
|
143
|
+
__proto__: null,
|
|
144
|
+
...options
|
|
145
|
+
};
|
|
138
146
|
if (node_os.default.platform() !== "darwin") return {
|
|
139
147
|
rcPath: void 0,
|
|
140
148
|
outcome: "skipped",
|
|
141
149
|
reason: "unsupported-platform"
|
|
142
150
|
};
|
|
143
|
-
const rcPath =
|
|
151
|
+
const rcPath = options.rcPath ?? pickRcFile(options.shell);
|
|
144
152
|
if (!rcPath) return {
|
|
145
153
|
rcPath: void 0,
|
|
146
154
|
outcome: "skipped",
|
|
147
155
|
reason: "unknown-shell"
|
|
148
156
|
};
|
|
149
|
-
const { begin, end, full: desiredBlock } = buildBlock(
|
|
157
|
+
const { begin, end, full: desiredBlock } = buildBlock(options);
|
|
150
158
|
let onDisk = "";
|
|
151
159
|
if ((0, node_fs.existsSync)(rcPath)) onDisk = (0, node_fs.readFileSync)(rcPath, "utf8");
|
|
152
160
|
let working = onDisk;
|
|
153
|
-
for (const legacyBegin of
|
|
161
|
+
for (const legacyBegin of options.legacySentinels ?? []) {
|
|
154
162
|
const legacyEnd = legacyBegin.replace(/\bBEGIN\b/, "END");
|
|
155
163
|
const legacyEndStripped = legacyEnd.replace(/\s*\(managed\)\s*$/, "");
|
|
156
164
|
const endAlt = legacyEnd === legacyEndStripped ? escapeRegExp(legacyEnd) : `(?:${escapeRegExp(legacyEnd)}|${escapeRegExp(legacyEndStripped)})`;
|
|
@@ -17,6 +17,10 @@ const SOCKET_SERVICE = "socketsecurity";
|
|
|
17
17
|
const SOCKET_SERVICE_LEGACY = "socket-cli";
|
|
18
18
|
const TOKEN_ACCOUNTS = ["SOCKET_API_TOKEN", "SOCKET_API_KEY"];
|
|
19
19
|
async function readSocketApiToken(options) {
|
|
20
|
+
options = {
|
|
21
|
+
__proto__: null,
|
|
22
|
+
...options
|
|
23
|
+
};
|
|
20
24
|
return (await require_secrets_find.resolve({
|
|
21
25
|
service: SOCKET_SERVICE,
|
|
22
26
|
accounts: TOKEN_ACCOUNTS,
|
|
@@ -28,6 +32,10 @@ async function readSocketApiToken(options) {
|
|
|
28
32
|
}))?.value;
|
|
29
33
|
}
|
|
30
34
|
function readSocketApiTokenSync(options) {
|
|
35
|
+
options = {
|
|
36
|
+
__proto__: null,
|
|
37
|
+
...options
|
|
38
|
+
};
|
|
31
39
|
return (require_secrets_find.resolveSync({
|
|
32
40
|
service: SOCKET_SERVICE,
|
|
33
41
|
accounts: TOKEN_ACCOUNTS,
|
package/dist/secrets/windows.js
CHANGED
|
@@ -4,14 +4,13 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
4
4
|
const require_runtime = require('../_virtual/_rolldown/runtime.js');
|
|
5
5
|
const require_primordials_error = require('../primordials/error.js');
|
|
6
6
|
const require_primordials_json = require('../primordials/json.js');
|
|
7
|
-
const require_primordials_promise = require('../primordials/promise.js');
|
|
8
7
|
let node_fs = require("node:fs");
|
|
8
|
+
let node_process = require("node:process");
|
|
9
|
+
node_process = require_runtime.__toESM(node_process);
|
|
9
10
|
let node_path = require("node:path");
|
|
10
11
|
node_path = require_runtime.__toESM(node_path);
|
|
11
12
|
let node_os = require("node:os");
|
|
12
13
|
node_os = require_runtime.__toESM(node_os);
|
|
13
|
-
let node_process = require("node:process");
|
|
14
|
-
node_process = require_runtime.__toESM(node_process);
|
|
15
14
|
let _socketsecurity_lib_stable_process_spawn_child = require("@socketsecurity/lib-stable/process/spawn/child");
|
|
16
15
|
|
|
17
16
|
//#region src/secrets/windows.ts
|
|
@@ -128,40 +127,35 @@ function readWindowsSync(service, account) {
|
|
|
128
127
|
}
|
|
129
128
|
return readDpapiSync(getDpapiFilePath(service, account));
|
|
130
129
|
}
|
|
131
|
-
function runPsAsync(script, input) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
130
|
+
async function runPsAsync(script, input) {
|
|
131
|
+
const child = (0, _socketsecurity_lib_stable_process_spawn_child.spawn)(POWERSHELL_BIN, [
|
|
132
|
+
"-NoProfile",
|
|
133
|
+
"-Command",
|
|
134
|
+
script
|
|
135
|
+
], {
|
|
136
|
+
stdio: [
|
|
138
137
|
"pipe",
|
|
139
138
|
"pipe",
|
|
140
139
|
"pipe"
|
|
141
|
-
]
|
|
142
|
-
|
|
143
|
-
let stderr = "";
|
|
144
|
-
cp.stdout.setEncoding("utf8");
|
|
145
|
-
cp.stdout.on("data", (chunk) => {
|
|
146
|
-
stdout += chunk;
|
|
147
|
-
});
|
|
148
|
-
cp.stderr.setEncoding("utf8");
|
|
149
|
-
cp.stderr.on("data", (chunk) => {
|
|
150
|
-
stderr += chunk;
|
|
151
|
-
});
|
|
152
|
-
cp.on("error", () => resolve({
|
|
153
|
-
status: -1,
|
|
154
|
-
stdout,
|
|
155
|
-
stderr
|
|
156
|
-
}));
|
|
157
|
-
cp.on("close", (status) => resolve({
|
|
158
|
-
status,
|
|
159
|
-
stdout,
|
|
160
|
-
stderr
|
|
161
|
-
}));
|
|
162
|
-
if (input !== void 0) cp.stdin.end(input);
|
|
163
|
-
else cp.stdin.end();
|
|
140
|
+
],
|
|
141
|
+
stdioString: true
|
|
164
142
|
});
|
|
143
|
+
child.process.stdin.end(input ?? "");
|
|
144
|
+
try {
|
|
145
|
+
const r = await child;
|
|
146
|
+
return {
|
|
147
|
+
status: typeof r.code === "number" ? r.code : null,
|
|
148
|
+
stderr: String(r.stderr ?? ""),
|
|
149
|
+
stdout: String(r.stdout ?? "")
|
|
150
|
+
};
|
|
151
|
+
} catch (e) {
|
|
152
|
+
const err = e;
|
|
153
|
+
return {
|
|
154
|
+
status: typeof err?.code === "number" ? err.code : -1,
|
|
155
|
+
stderr: String(err?.stderr ?? ""),
|
|
156
|
+
stdout: String(err?.stdout ?? "")
|
|
157
|
+
};
|
|
158
|
+
}
|
|
165
159
|
}
|
|
166
160
|
function runPsSync(script, input) {
|
|
167
161
|
const r = (0, _socketsecurity_lib_stable_process_spawn_child.spawnSync)(POWERSHELL_BIN, [
|
package/dist/shell/parse.d.ts
CHANGED
|
@@ -8,6 +8,38 @@
|
|
|
8
8
|
* against `env`; unresolved ones collapse to an empty string.
|
|
9
9
|
*/
|
|
10
10
|
import type { ParseEntry } from '../external/shell-quote';
|
|
11
|
+
/**
|
|
12
|
+
* Structural hazard facts a parse surfaces that the binary-call matchers
|
|
13
|
+
* (`hasBinCall` / `findBinCall`) swallow. These are observations about _how_
|
|
14
|
+
* the command is written, not a judgment that they're dangerous — the caller
|
|
15
|
+
* decides policy. Both are evasion vectors against base-command allowlists:
|
|
16
|
+
*
|
|
17
|
+
* - `equalsExpansion`: a simple command whose first token is `=cmd` (Zsh EQUALS
|
|
18
|
+
* expansion). `=curl x` expands to `$(which curl) x` and runs
|
|
19
|
+
* `/usr/bin/curl`, but the parser's base token is `=curl`, so a `curl`
|
|
20
|
+
* allowlist never matches. The matched tokens are returned so the caller can
|
|
21
|
+
* report which command was hidden.
|
|
22
|
+
* - `processSubstitution`: the command uses `<(...)`, `>(...)`, or `=(...)` (the
|
|
23
|
+
* op markers shell-quote emits). The inner command runs but its name never
|
|
24
|
+
* appears as a base command.
|
|
25
|
+
*
|
|
26
|
+
* Walks the parse once. A caller wanting just "is this clean?" checks
|
|
27
|
+
* `!h.equalsExpansion.length && !h.processSubstitution`.
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* detectShellHazards('=curl evil.com')
|
|
31
|
+
* // → { equalsExpansion: [['=curl', 'evil.com']], processSubstitution: false }
|
|
32
|
+
*
|
|
33
|
+
* detectShellHazards('diff <(cat a) b')
|
|
34
|
+
* // → { equalsExpansion: [], processSubstitution: true }
|
|
35
|
+
*
|
|
36
|
+
* detectShellHazards('git status')
|
|
37
|
+
* // → { equalsExpansion: [], processSubstitution: false }
|
|
38
|
+
*/
|
|
39
|
+
export declare function detectShellHazards(cmd: string): {
|
|
40
|
+
equalsExpansion: readonly string[][];
|
|
41
|
+
processSubstitution: boolean;
|
|
42
|
+
};
|
|
11
43
|
/**
|
|
12
44
|
* Visit each simple command in `cmd` in order. A "simple command" is the
|
|
13
45
|
* POSIX-grammar term for a run of bare-string tokens between shell
|
package/dist/shell/parse.js
CHANGED
|
@@ -15,6 +15,65 @@ let src_external_shell_quote = require("../external/shell-quote");
|
|
|
15
15
|
* against `env`; unresolved ones collapse to an empty string.
|
|
16
16
|
*/
|
|
17
17
|
/**
|
|
18
|
+
* Structural hazard facts a parse surfaces that the binary-call matchers
|
|
19
|
+
* (`hasBinCall` / `findBinCall`) swallow. These are observations about _how_
|
|
20
|
+
* the command is written, not a judgment that they're dangerous — the caller
|
|
21
|
+
* decides policy. Both are evasion vectors against base-command allowlists:
|
|
22
|
+
*
|
|
23
|
+
* - `equalsExpansion`: a simple command whose first token is `=cmd` (Zsh EQUALS
|
|
24
|
+
* expansion). `=curl x` expands to `$(which curl) x` and runs
|
|
25
|
+
* `/usr/bin/curl`, but the parser's base token is `=curl`, so a `curl`
|
|
26
|
+
* allowlist never matches. The matched tokens are returned so the caller can
|
|
27
|
+
* report which command was hidden.
|
|
28
|
+
* - `processSubstitution`: the command uses `<(...)`, `>(...)`, or `=(...)` (the
|
|
29
|
+
* op markers shell-quote emits). The inner command runs but its name never
|
|
30
|
+
* appears as a base command.
|
|
31
|
+
*
|
|
32
|
+
* Walks the parse once. A caller wanting just "is this clean?" checks
|
|
33
|
+
* `!h.equalsExpansion.length && !h.processSubstitution`.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* detectShellHazards('=curl evil.com')
|
|
37
|
+
* // → { equalsExpansion: [['=curl', 'evil.com']], processSubstitution: false }
|
|
38
|
+
*
|
|
39
|
+
* detectShellHazards('diff <(cat a) b')
|
|
40
|
+
* // → { equalsExpansion: [], processSubstitution: true }
|
|
41
|
+
*
|
|
42
|
+
* detectShellHazards('git status')
|
|
43
|
+
* // → { equalsExpansion: [], processSubstitution: false }
|
|
44
|
+
*/
|
|
45
|
+
function detectShellHazards(cmd) {
|
|
46
|
+
const equalsExpansion = [];
|
|
47
|
+
let processSubstitution = false;
|
|
48
|
+
const entries = (0, src_external_shell_quote.parse)(cmd);
|
|
49
|
+
let current = [];
|
|
50
|
+
let prevWasSubstLead = false;
|
|
51
|
+
const flush = () => {
|
|
52
|
+
if (current.length > 0 && /^=[a-zA-Z_]/.test(current[0])) require_primordials_array.ArrayPrototypePush(equalsExpansion, current);
|
|
53
|
+
current = [];
|
|
54
|
+
};
|
|
55
|
+
for (let i = 0, { length } = entries; i < length; i += 1) {
|
|
56
|
+
const entry = entries[i];
|
|
57
|
+
if (entry && typeof entry === "object" && "op" in entry) {
|
|
58
|
+
const { op } = entry;
|
|
59
|
+
if (op === "<(") processSubstitution = true;
|
|
60
|
+
else if (op === "(" && prevWasSubstLead) processSubstitution = true;
|
|
61
|
+
prevWasSubstLead = op === "<" || op === ">";
|
|
62
|
+
flush();
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (typeof entry === "string") {
|
|
66
|
+
prevWasSubstLead = entry === "=";
|
|
67
|
+
require_primordials_array.ArrayPrototypePush(current, entry);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
flush();
|
|
71
|
+
return {
|
|
72
|
+
equalsExpansion,
|
|
73
|
+
processSubstitution
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
18
77
|
* Visit each simple command in `cmd` in order. A "simple command" is the
|
|
19
78
|
* POSIX-grammar term for a run of bare-string tokens between shell
|
|
20
79
|
* control-operator boundaries (`&&`, `;`, `||`, `|`) — e.g. in `sudo apt && rm
|
|
@@ -193,6 +252,7 @@ function simpleCommandStartsWith(tokens, prefix) {
|
|
|
193
252
|
}
|
|
194
253
|
|
|
195
254
|
//#endregion
|
|
255
|
+
exports.detectShellHazards = detectShellHazards;
|
|
196
256
|
exports.eachSimpleCommand = eachSimpleCommand;
|
|
197
257
|
exports.findBinCall = findBinCall;
|
|
198
258
|
exports.findBinCalls = findBinCalls;
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
/* Socket Lib - Built with rolldown */
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
4
|
const require_primordials_math = require('../primordials/math.js');
|
|
5
|
-
const require_primordials_array = require('../primordials/array.js');
|
|
6
5
|
const require_primordials_object = require('../primordials/object.js');
|
|
6
|
+
const require_primordials_array = require('../primordials/array.js');
|
|
7
|
+
const require_process_abort = require('../process/abort.js');
|
|
7
8
|
const require_logger_symbols = require('../logger/symbols.js');
|
|
8
9
|
const require_strings_predicates = require('../strings/predicates.js');
|
|
9
|
-
const require_process_abort = require('../process/abort.js');
|
|
10
10
|
const require_colors_convert = require('../colors/convert.js');
|
|
11
11
|
const require_strings_width = require('../strings/width.js');
|
|
12
12
|
const require_spinner_format = require('./format.js');
|
|
@@ -33,4 +33,4 @@ export declare function parseShimmerOption(shimmer: SpinnerOptions['shimmer']):
|
|
|
33
33
|
*
|
|
34
34
|
* @returns Resolved RGB color tuple.
|
|
35
35
|
*/
|
|
36
|
-
export declare function resolveSpinnerColorRgb(
|
|
36
|
+
export declare function resolveSpinnerColorRgb(options: SpinnerOptions): ColorRgb;
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
4
|
const require_primordials_error = require('../primordials/error.js');
|
|
5
5
|
const require_primordials_array = require('../primordials/array.js');
|
|
6
|
+
const require_env_ci = require('../env/ci.js');
|
|
6
7
|
const require_themes_themes = require('../themes/themes.js');
|
|
7
8
|
const require_themes_context = require('../themes/context.js');
|
|
8
|
-
const require_env_ci = require('../env/ci.js');
|
|
9
9
|
const require_colors_convert = require('../colors/convert.js');
|
|
10
10
|
const require_spinner_format = require('./format.js');
|
|
11
11
|
const require_effects_shimmer = require('../effects/shimmer.js');
|
|
@@ -80,17 +80,21 @@ function parseShimmerOption(shimmer) {
|
|
|
80
80
|
*
|
|
81
81
|
* @returns Resolved RGB color tuple.
|
|
82
82
|
*/
|
|
83
|
-
function resolveSpinnerColorRgb(
|
|
83
|
+
function resolveSpinnerColorRgb(options) {
|
|
84
|
+
options = {
|
|
85
|
+
__proto__: null,
|
|
86
|
+
...options
|
|
87
|
+
};
|
|
84
88
|
let theme = require_themes_context.getTheme();
|
|
85
|
-
if (
|
|
86
|
-
else theme =
|
|
89
|
+
if (options.theme) if (typeof options.theme === "string") theme = require_themes_themes.THEMES[options.theme] ?? theme;
|
|
90
|
+
else theme = options.theme;
|
|
87
91
|
let defaultColor = theme.colors.primary;
|
|
88
92
|
if (theme.effects?.spinner?.color) {
|
|
89
93
|
const resolved = require_themes_resolve.resolveColor(theme.effects.spinner.color, theme.colors);
|
|
90
94
|
if (resolved === "inherit" || require_primordials_array.ArrayIsArray(resolved[0])) defaultColor = theme.colors.primary;
|
|
91
95
|
else defaultColor = resolved;
|
|
92
96
|
}
|
|
93
|
-
const spinnerColor =
|
|
97
|
+
const spinnerColor = options.color ?? defaultColor;
|
|
94
98
|
if (require_colors_convert.isRgbTuple(spinnerColor) && (spinnerColor.length !== 3 || !spinnerColor.every((n) => typeof n === "number" && n >= 0 && n <= 255))) throw new require_primordials_error.TypeErrorCtor("RGB color must be an array of 3 numbers between 0 and 255");
|
|
95
99
|
return require_colors_convert.toRgb(spinnerColor);
|
|
96
100
|
}
|
|
@@ -7,7 +7,11 @@
|
|
|
7
7
|
* the live `YoctoSpinner` constructor resolved here; building it lazily keeps
|
|
8
8
|
* the module free of side effects at import time.
|
|
9
9
|
*/
|
|
10
|
+
import type { YoctoSpinnerConstructor } from './create-spinner-class';
|
|
10
11
|
import type { SpinnerInstance, SpinnerOptions } from './types';
|
|
12
|
+
export type YoctoSpinnerFactory = (options: Record<string, unknown>) => {
|
|
13
|
+
constructor: YoctoSpinnerConstructor;
|
|
14
|
+
};
|
|
11
15
|
/**
|
|
12
16
|
* Create a spinner instance for displaying loading indicators. Provides an
|
|
13
17
|
* animated CLI spinner with status messages, progress tracking, and shimmer
|
package/dist/spinner/spinner.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
/* Socket Lib - Built with rolldown */
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
4
|
const require_runtime = require('../_virtual/_rolldown/runtime.js');
|
|
5
|
-
const require_logger_default = require('../logger/default.js');
|
|
6
5
|
const require_env_ci = require('../env/ci.js');
|
|
6
|
+
const require_logger_default = require('../logger/default.js');
|
|
7
7
|
const require_spinner_format = require('./format.js');
|
|
8
8
|
const require_spinner_create_spinner_class = require('./create-spinner-class.js');
|
|
9
9
|
const require_spinner_default = require('./default.js');
|
package/dist/stdio/progress.js
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
4
|
const require_runtime = require('../_virtual/_rolldown/runtime.js');
|
|
5
5
|
const require_primordials_math = require('../primordials/math.js');
|
|
6
|
+
const require_primordials_object = require('../primordials/object.js');
|
|
6
7
|
const require_primordials_string = require('../primordials/string.js');
|
|
7
8
|
const require_primordials_date = require('../primordials/date.js');
|
|
8
|
-
const require_primordials_object = require('../primordials/object.js');
|
|
9
9
|
const require_ansi_strip = require('../ansi/strip.js');
|
|
10
10
|
const require_strings_format = require('../strings/format.js');
|
|
11
11
|
let node_process = require("node:process");
|
|
@@ -43,6 +43,10 @@ var ProgressBar = class {
|
|
|
43
43
|
* @param options - Configuration options for the progress bar.
|
|
44
44
|
*/
|
|
45
45
|
constructor(total, options) {
|
|
46
|
+
options = {
|
|
47
|
+
__proto__: null,
|
|
48
|
+
...options
|
|
49
|
+
};
|
|
46
50
|
this.total = total;
|
|
47
51
|
this.startTime = require_primordials_date.DateNow();
|
|
48
52
|
this.stream = options?.stream || node_process.default.stderr;
|
package/dist/stdio/prompts.d.ts
CHANGED
|
@@ -45,7 +45,7 @@ export interface Choice<Value = unknown> {
|
|
|
45
45
|
* Context for inquirer prompts. Minimal context interface used by Inquirer
|
|
46
46
|
* prompts. Duplicated from `@inquirer/type` - InquirerContext.
|
|
47
47
|
*/
|
|
48
|
-
interface InquirerContext {
|
|
48
|
+
export interface InquirerContext {
|
|
49
49
|
/**
|
|
50
50
|
* Abort signal for cancelling the prompt.
|
|
51
51
|
*/
|
|
@@ -88,7 +88,7 @@ export type Context = Remap<InquirerContext & {
|
|
|
88
88
|
* { name: 'Option 2', value: 2 },
|
|
89
89
|
* ]
|
|
90
90
|
*/
|
|
91
|
-
declare class SeparatorType {
|
|
91
|
+
export declare class SeparatorType {
|
|
92
92
|
readonly separator: string;
|
|
93
93
|
readonly type: 'separator';
|
|
94
94
|
constructor(separator?: string);
|
package/dist/stdio/prompts.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/* Socket Lib - Built with rolldown */
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
4
|
const require_runtime = require('../_virtual/_rolldown/runtime.js');
|
|
5
|
+
const require_process_abort = require('../process/abort.js');
|
|
5
6
|
const require_themes_themes = require('../themes/themes.js');
|
|
6
7
|
const require_themes_context = require('../themes/context.js');
|
|
7
|
-
const require_process_abort = require('../process/abort.js');
|
|
8
8
|
const require_themes_resolve = require('../themes/resolve.js');
|
|
9
9
|
const require_spinner_default = require('../spinner/default.js');
|
|
10
10
|
let src_external_yoctocolors_cjs = require("../external/yoctocolors-cjs");
|
package/dist/temporal/instant.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
/* Socket Lib - Built with rolldown */
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
4
|
const require_primordials_error = require('../primordials/error.js');
|
|
5
|
-
const require_primordials_json = require('../primordials/json.js');
|
|
6
5
|
const require_primordials_object = require('../primordials/object.js');
|
|
6
|
+
const require_primordials_json = require('../primordials/json.js');
|
|
7
7
|
const require_primordials_globals = require('../primordials/globals.js');
|
|
8
8
|
const require_temporal_slots = require('./slots.js');
|
|
9
9
|
|
|
@@ -72,7 +72,7 @@ function describe(value) {
|
|
|
72
72
|
if (typeof value === "bigint") return `${value}n`;
|
|
73
73
|
if (typeof value === "object") {
|
|
74
74
|
const ctor = value.constructor;
|
|
75
|
-
return ctor
|
|
75
|
+
return ctor?.name ? `<${ctor.name}>` : "<object>";
|
|
76
76
|
}
|
|
77
77
|
return typeof value === "string" ? require_primordials_json.JSONStringify(value) : String(value);
|
|
78
78
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file SSRF guard for operator- or issuer-supplied URLs — `assertSafeHttpUrl`
|
|
3
|
+
* parses a raw URL, rejects non-HTTP(S) schemes, and refuses hosts that
|
|
4
|
+
* resolve to loopback / private / link-local ranges (cloud metadata, redis,
|
|
5
|
+
* internal services). A server that fetches a URL it did not author (an OAuth
|
|
6
|
+
* issuer, an introspection endpoint advertised in its metadata, a webhook
|
|
7
|
+
* target) runs the candidate through this before the request leaves the box.
|
|
8
|
+
*/
|
|
9
|
+
import type { AssertSafeHttpUrlOptions } from './types';
|
|
10
|
+
/**
|
|
11
|
+
* Parse `rawUrl` and assert it is safe to fetch server-side, returning the
|
|
12
|
+
* parsed `URL`. Throws when the value does not parse, uses a scheme other than
|
|
13
|
+
* `http:` / `https:`, or resolves to a loopback / private / link-local host.
|
|
14
|
+
* Set `allowLocalhost` to permit `localhost` / `127.0.0.1` / `::1` for
|
|
15
|
+
* local-stack development. `label` names the subject in the thrown message.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ;```typescript
|
|
19
|
+
* assertSafeHttpUrl('https://api.example.com', { label: 'OAuth issuer' })
|
|
20
|
+
* // → URL { href: 'https://api.example.com/' }
|
|
21
|
+
*
|
|
22
|
+
* assertSafeHttpUrl('http://169.254.169.254/latest/meta-data')
|
|
23
|
+
* // → throws: resolves to a private/loopback host
|
|
24
|
+
*
|
|
25
|
+
* assertSafeHttpUrl('ftp://example.com')
|
|
26
|
+
* // → throws: must use http(s)
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare function assertSafeHttpUrl(rawUrl: string, options?: AssertSafeHttpUrlOptions | undefined): URL;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Socket Lib - Built with rolldown */
|
|
3
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
|
+
const require_url_predicates = require('./predicates.js');
|
|
5
|
+
|
|
6
|
+
//#region src/url/assert-safe.ts
|
|
7
|
+
/**
|
|
8
|
+
* @file SSRF guard for operator- or issuer-supplied URLs — `assertSafeHttpUrl`
|
|
9
|
+
* parses a raw URL, rejects non-HTTP(S) schemes, and refuses hosts that
|
|
10
|
+
* resolve to loopback / private / link-local ranges (cloud metadata, redis,
|
|
11
|
+
* internal services). A server that fetches a URL it did not author (an OAuth
|
|
12
|
+
* issuer, an introspection endpoint advertised in its metadata, a webhook
|
|
13
|
+
* target) runs the candidate through this before the request leaves the box.
|
|
14
|
+
*/
|
|
15
|
+
const UrlCtor = URL;
|
|
16
|
+
/**
|
|
17
|
+
* Parse `rawUrl` and assert it is safe to fetch server-side, returning the
|
|
18
|
+
* parsed `URL`. Throws when the value does not parse, uses a scheme other than
|
|
19
|
+
* `http:` / `https:`, or resolves to a loopback / private / link-local host.
|
|
20
|
+
* Set `allowLocalhost` to permit `localhost` / `127.0.0.1` / `::1` for
|
|
21
|
+
* local-stack development. `label` names the subject in the thrown message.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ;```typescript
|
|
25
|
+
* assertSafeHttpUrl('https://api.example.com', { label: 'OAuth issuer' })
|
|
26
|
+
* // → URL { href: 'https://api.example.com/' }
|
|
27
|
+
*
|
|
28
|
+
* assertSafeHttpUrl('http://169.254.169.254/latest/meta-data')
|
|
29
|
+
* // → throws: resolves to a private/loopback host
|
|
30
|
+
*
|
|
31
|
+
* assertSafeHttpUrl('ftp://example.com')
|
|
32
|
+
* // → throws: must use http(s)
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
function assertSafeHttpUrl(rawUrl, options) {
|
|
36
|
+
const { allowLocalhost = false, label = "URL" } = {
|
|
37
|
+
__proto__: null,
|
|
38
|
+
...options
|
|
39
|
+
};
|
|
40
|
+
let url;
|
|
41
|
+
try {
|
|
42
|
+
url = new UrlCtor(rawUrl);
|
|
43
|
+
} catch {
|
|
44
|
+
throw new Error(`${label} is not a valid URL: ${rawUrl}. Provide an absolute http(s) URL.`);
|
|
45
|
+
}
|
|
46
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") throw new Error(`${label} must use http(s): ${rawUrl}. Got scheme "${url.protocol}"; use http: or https:.`);
|
|
47
|
+
const { hostname } = url;
|
|
48
|
+
if (allowLocalhost && require_url_predicates.isLoopbackHost(hostname)) return url;
|
|
49
|
+
if (require_url_predicates.isPrivateHost(hostname)) throw new Error(`${label} resolves to a private/loopback host and is refused: ${rawUrl}. Point it at a public host.`);
|
|
50
|
+
return url;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
//#endregion
|
|
54
|
+
exports.assertSafeHttpUrl = assertSafeHttpUrl;
|
package/dist/url/predicates.d.ts
CHANGED
|
@@ -1,7 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file URL type-guard predicates — `isUrl` answers whether a value parses as a
|
|
3
|
-
* valid URL via `parseUrl`.
|
|
3
|
+
* valid URL via `parseUrl`. `isLoopbackHost` / `isPrivateHost` classify a
|
|
4
|
+
* hostname for SSRF guards: a server that fetches an operator- or
|
|
5
|
+
* issuer-supplied URL uses these to refuse hosts that resolve to the local
|
|
6
|
+
* machine or an internal network (cloud metadata, redis, link-local).
|
|
4
7
|
*/
|
|
8
|
+
/**
|
|
9
|
+
* Check whether a hostname is a loopback address — `localhost`, `127.0.0.1`, or
|
|
10
|
+
* IPv6 `::1`. Compares case-insensitively; pass a bare hostname, not a URL.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ;```typescript
|
|
14
|
+
* isLoopbackHost('localhost') // true
|
|
15
|
+
* isLoopbackHost('127.0.0.1') // true
|
|
16
|
+
* isLoopbackHost('example.com') // false
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare function isLoopbackHost(hostname: string): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Check whether a hostname resolves to a private / loopback / link-local
|
|
22
|
+
* address an SSRF probe would target (the local machine, RFC 1918 ranges, IPv6
|
|
23
|
+
* loopback / ULA / link-local). Loopback hosts count as private. Compares
|
|
24
|
+
* case-insensitively; pass a bare hostname, not a URL.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ;```typescript
|
|
28
|
+
* isPrivateHost('127.0.0.1') // true
|
|
29
|
+
* isPrivateHost('10.0.0.5') // true
|
|
30
|
+
* isPrivateHost('169.254.169.254') // true
|
|
31
|
+
* isPrivateHost('example.com') // false
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare function isPrivateHost(hostname: string): boolean;
|
|
5
35
|
/**
|
|
6
36
|
* Check if a value is a valid URL.
|
|
7
37
|
*
|
package/dist/url/predicates.js
CHANGED
|
@@ -1,13 +1,52 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/* Socket Lib - Built with rolldown */
|
|
3
3
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
4
|
+
const require_primordials_string = require('../primordials/string.js');
|
|
5
|
+
const require_primordials_regexp = require('../primordials/regexp.js');
|
|
4
6
|
const require_url_parse = require('./parse.js');
|
|
5
7
|
|
|
6
8
|
//#region src/url/predicates.ts
|
|
7
9
|
/**
|
|
8
10
|
* @file URL type-guard predicates — `isUrl` answers whether a value parses as a
|
|
9
|
-
* valid URL via `parseUrl`.
|
|
11
|
+
* valid URL via `parseUrl`. `isLoopbackHost` / `isPrivateHost` classify a
|
|
12
|
+
* hostname for SSRF guards: a server that fetches an operator- or
|
|
13
|
+
* issuer-supplied URL uses these to refuse hosts that resolve to the local
|
|
14
|
+
* machine or an internal network (cloud metadata, redis, link-local).
|
|
10
15
|
*/
|
|
16
|
+
const PRIVATE_HOST_REGEXP = /^(?:0\.0\.0\.0$|10\.|127\.|169\.254\.|172\.(?:1[6-9]|2\d|3[01])\.|192\.168\.|\[?::1\]?$|\[?fc00:|\[?fd|\[?fe80:)/u;
|
|
17
|
+
/**
|
|
18
|
+
* Check whether a hostname is a loopback address — `localhost`, `127.0.0.1`, or
|
|
19
|
+
* IPv6 `::1`. Compares case-insensitively; pass a bare hostname, not a URL.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ;```typescript
|
|
23
|
+
* isLoopbackHost('localhost') // true
|
|
24
|
+
* isLoopbackHost('127.0.0.1') // true
|
|
25
|
+
* isLoopbackHost('example.com') // false
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
function isLoopbackHost(hostname) {
|
|
29
|
+
const host = require_primordials_string.StringPrototypeToLowerCase(hostname);
|
|
30
|
+
return host === "::1" || host === "127.0.0.1" || host === "localhost";
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Check whether a hostname resolves to a private / loopback / link-local
|
|
34
|
+
* address an SSRF probe would target (the local machine, RFC 1918 ranges, IPv6
|
|
35
|
+
* loopback / ULA / link-local). Loopback hosts count as private. Compares
|
|
36
|
+
* case-insensitively; pass a bare hostname, not a URL.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ;```typescript
|
|
40
|
+
* isPrivateHost('127.0.0.1') // true
|
|
41
|
+
* isPrivateHost('10.0.0.5') // true
|
|
42
|
+
* isPrivateHost('169.254.169.254') // true
|
|
43
|
+
* isPrivateHost('example.com') // false
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
function isPrivateHost(hostname) {
|
|
47
|
+
const host = require_primordials_string.StringPrototypeToLowerCase(hostname);
|
|
48
|
+
return isLoopbackHost(host) || require_primordials_regexp.RegExpPrototypeTest(PRIVATE_HOST_REGEXP, host);
|
|
49
|
+
}
|
|
11
50
|
/**
|
|
12
51
|
* Check if a value is a valid URL.
|
|
13
52
|
*
|
|
@@ -23,4 +62,6 @@ function isUrl(value) {
|
|
|
23
62
|
}
|
|
24
63
|
|
|
25
64
|
//#endregion
|
|
65
|
+
exports.isLoopbackHost = isLoopbackHost;
|
|
66
|
+
exports.isPrivateHost = isPrivateHost;
|
|
26
67
|
exports.isUrl = isUrl;
|
package/dist/url/types.d.ts
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
* `createRelativeUrl`, `urlSearchParamsAs*`, and `urlSearchParamsGet*`. Pure
|
|
4
4
|
* types, no runtime side effects.
|
|
5
5
|
*/
|
|
6
|
+
export interface AssertSafeHttpUrlOptions {
|
|
7
|
+
label?: string | undefined;
|
|
8
|
+
allowLocalhost?: boolean | undefined;
|
|
9
|
+
}
|
|
6
10
|
export interface CreateRelativeUrlOptions {
|
|
7
11
|
base?: string | undefined;
|
|
8
12
|
}
|