@socketsecurity/lib 6.0.0 → 6.0.2
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 +91 -0
- package/README.md +26 -17
- package/dist/ai/discover.js +2 -2
- package/dist/ai/spawn.js +3 -3
- package/dist/ai/worktree.js +3 -3
- package/dist/argv/parse-args-string.d.ts +30 -0
- package/dist/argv/parse-args-string.js +42 -0
- package/dist/bin/check-primordials.js +15 -10
- package/dist/bin/check.js +2 -2
- package/dist/bin/exec.d.ts +1 -1
- package/dist/bin/exec.js +2 -2
- package/dist/bin/socket-lib.js +2 -2
- package/dist/{ttl-cache/cache.js → cache/ttl/store.js} +15 -15
- package/dist/{ttl-cache → cache/ttl}/types.d.ts +1 -1
- package/dist/checks/primordials-defaults.d.ts +20 -0
- package/dist/checks/primordials-defaults.js +92 -0
- package/dist/colors/socket-palette.d.ts +69 -0
- package/dist/colors/socket-palette.js +91 -0
- package/dist/constants/socket.js +1 -1
- package/dist/cover/code.js +2 -2
- package/dist/cover/type.js +2 -2
- package/dist/debug/_internal.d.ts +1 -1
- package/dist/debug/_internal.js +2 -2
- package/dist/debug/output.js +5 -5
- package/dist/dlx/binary-types.d.ts +2 -2
- package/dist/dlx/binary.d.ts +2 -2
- package/dist/dlx/binary.js +3 -3
- package/dist/dlx/firewall.js +2 -2
- package/dist/dlx/manifest.js +2 -2
- package/dist/dlx/package.d.ts +2 -2
- package/dist/dlx/package.js +2 -2
- package/dist/dlx/types.d.ts +2 -2
- package/dist/eco/npm/npm/exec.d.ts +2 -2
- package/dist/eco/npm/npm/exec.js +2 -2
- package/dist/eco/npm/pnpm/exec.d.ts +1 -1
- package/dist/eco/npm/script.d.ts +1 -1
- package/dist/eco/npm/script.js +3 -3
- package/dist/eco/npm/yarnpkg/yarn/exec.d.ts +1 -1
- package/dist/{signal-exit → events/exit}/_internal.d.ts +1 -1
- package/dist/{signal-exit/register.js → events/exit/handler.js} +4 -4
- package/dist/{signal-exit → events/exit}/intercept.js +2 -2
- package/dist/{signal-exit → events/exit}/types.d.ts +1 -1
- package/dist/{warnings/event-target.d.ts → events/warning/handler.d.ts} +1 -1
- package/dist/{warnings/event-target.js → events/warning/handler.js} +4 -4
- package/dist/{warnings → events/warning}/suppress.d.ts +3 -3
- package/dist/{warnings → events/warning}/suppress.js +2 -2
- package/dist/external-tools/janus/asset-names.d.ts +7 -0
- package/dist/external-tools/janus/asset-names.js +5 -0
- package/dist/external-tools/janus/from-download.d.ts +1 -1
- package/dist/external-tools/janus/from-download.js +12 -4
- package/dist/fs/read-json-cache.d.ts +83 -0
- package/dist/fs/read-json-cache.js +156 -0
- package/dist/fs/read-json.d.ts +6 -1
- package/dist/fs/read-json.js +80 -8
- package/dist/fs/types.d.ts +14 -0
- package/dist/git/_internal.js +3 -3
- package/dist/github/refs-cache.d.ts +1 -1
- package/dist/github/refs-cache.js +2 -2
- package/dist/github/token.d.ts +1 -1
- package/dist/github/token.js +2 -2
- package/dist/globs/{glob.js → match.js} +3 -3
- package/dist/http-request/browser-fetch.d.ts +10 -0
- package/dist/http-request/browser-fetch.js +32 -0
- package/dist/http-request/browser.d.ts +190 -0
- package/dist/http-request/browser.js +224 -0
- package/dist/http-request/download-types.d.ts +2 -2
- package/dist/http-request/http-request.d.ts +12 -0
- package/dist/http-request/http-request.js +36 -0
- package/dist/http-request/node.d.ts +29 -0
- package/dist/http-request/{convenience.js → node.js} +9 -3
- package/dist/http-request/request-attempt.js +4 -0
- package/dist/http-request/request-types.d.ts +15 -0
- package/dist/http-request/request.js +5 -0
- package/dist/links/{link.d.ts → create.d.ts} +2 -2
- package/dist/links/{link.js → create.js} +3 -3
- package/dist/logger/_internal.d.ts +1 -1
- package/dist/logger/browser.d.ts +18 -0
- package/dist/logger/browser.js +58 -0
- package/dist/logger/console.js +3 -3
- package/dist/logger/default.d.ts +11 -0
- package/dist/logger/default.js +37 -0
- package/dist/logger/logger.d.ts +8 -403
- package/dist/logger/logger.js +3 -827
- package/dist/logger/node.d.ts +400 -0
- package/dist/logger/node.js +856 -0
- package/dist/logger/symbols-builder.d.ts +1 -1
- package/dist/logger/types.d.ts +1 -1
- package/dist/packages/isolation.js +3 -3
- package/dist/packages/provenance.d.ts +42 -0
- package/dist/packages/provenance.js +71 -0
- package/dist/packages/types.d.ts +2 -0
- package/dist/primordials/globals.d.ts +6 -3
- package/dist/primordials/globals.js +15 -9
- package/dist/primordials/map-set.d.ts +35 -0
- package/dist/primordials/map-set.js +43 -0
- package/dist/primordials/url.d.ts +1 -1
- package/dist/process/lock-manager.js +4 -4
- package/dist/{spawn → process/spawn}/_internal.js +3 -3
- package/dist/{spawn/spawn.js → process/spawn/child.js} +13 -13
- package/dist/{spawn → process/spawn}/errors.js +5 -5
- package/dist/{spawn → process/spawn}/stdio.js +1 -1
- package/dist/{spawn → process/spawn}/types.d.ts +3 -3
- package/dist/promises/types.d.ts +15 -2
- package/dist/releases/github-archives.js +2 -2
- package/dist/releases/github-downloads.js +4 -4
- package/dist/spinner/{registry.d.ts → default.d.ts} +1 -1
- package/dist/spinner/{registry.js → default.js} +3 -3
- package/dist/spinner/spinner.js +4 -4
- package/dist/spinner/with.d.ts +1 -1
- package/dist/stdio/divider.js +2 -2
- package/dist/stdio/footer.js +2 -2
- package/dist/stdio/header.js +2 -2
- package/dist/stdio/prompts.js +2 -2
- package/package.json +410 -132
- package/dist/http-request/convenience.d.ts +0 -104
- package/dist/promise-queue/types.d.ts +0 -10
- package/dist/ttl-cache/types.js +0 -18
- /package/dist/{ttl-cache/cache.d.ts → cache/ttl/store.d.ts} +0 -0
- /package/dist/{promise-queue → cache/ttl}/types.js +0 -0
- /package/dist/{signal-exit → events/exit}/_internal.js +0 -0
- /package/dist/{signal-exit/register.d.ts → events/exit/handler.d.ts} +0 -0
- /package/dist/{signal-exit → events/exit}/intercept.d.ts +0 -0
- /package/dist/{signal-exit → events/exit}/lifecycle.d.ts +0 -0
- /package/dist/{signal-exit → events/exit}/lifecycle.js +0 -0
- /package/dist/{signal-exit → events/exit}/signals.d.ts +0 -0
- /package/dist/{signal-exit → events/exit}/signals.js +0 -0
- /package/dist/{signal-exit → events/exit}/types.js +0 -0
- /package/dist/globs/{glob.d.ts → match.d.ts} +0 -0
- /package/dist/{spawn → process/spawn}/_internal.d.ts +0 -0
- /package/dist/{spawn/spawn.d.ts → process/spawn/child.d.ts} +0 -0
- /package/dist/{spawn → process/spawn}/errors.d.ts +0 -0
- /package/dist/{spawn → process/spawn}/stdio.d.ts +0 -0
- /package/dist/{spawn → process/spawn}/types.js +0 -0
- /package/dist/{promise-queue → promises}/queue.d.ts +0 -0
- /package/dist/{promise-queue → promises}/queue.js +0 -0
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Browser-safe HTTP request layer — mirrors the public surface of
|
|
3
|
+
* `@socketsecurity/lib/http-request` (`httpJson`, `httpText`, `httpRequest`,
|
|
4
|
+
* `HttpResponseError`) but uses the browser's `fetch` API instead of Node's
|
|
5
|
+
* `node:https`. Designed for Chrome MV3 service workers, content scripts,
|
|
6
|
+
* popups, and any other browser context that doesn't have `node:http` /
|
|
7
|
+
* `node:https` / `node:stream`. Consumers import from
|
|
8
|
+
* `@socketsecurity/lib/http-request/browser` directly, OR from
|
|
9
|
+
* `@socketsecurity/lib/http-request` inside a bundler that resolves the
|
|
10
|
+
* `browser` package.json conditional (rolldown, vite, esbuild) — the bundler
|
|
11
|
+
* picks this entry automatically. API parity with the Node side is the goal —
|
|
12
|
+
* same function names, same option shapes (where browsers can support them),
|
|
13
|
+
* same error shape. Caveats:
|
|
14
|
+
*
|
|
15
|
+
* - `HttpResponse.body` is `Uint8Array` here, vs Node's `Buffer`. Most callers
|
|
16
|
+
* use `arrayBuffer()` / `text()` / `json()` and don't care.
|
|
17
|
+
* - `HttpResponse.headers` is `Record<string, string>` here, vs Node's
|
|
18
|
+
* `IncomingHttpHeaders` (which has array-valued headers like `set-cookie`).
|
|
19
|
+
* Browser `fetch()` flattens repeated headers per spec.
|
|
20
|
+
* - Hooks (`onRequest` / `onResponse`) are not yet supported in the browser
|
|
21
|
+
* path. Add when needed.
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Browser-side HTTP error. Mirrors the Node-side `HttpResponseError` shape
|
|
25
|
+
* (same `.name`, same `.response.status/statusText` access pattern, same
|
|
26
|
+
* `instanceof` semantics) but constructs from a `BrowserHttpResponse` instead
|
|
27
|
+
* of a Node `HttpResponse`.
|
|
28
|
+
*/
|
|
29
|
+
export declare class HttpResponseError extends Error {
|
|
30
|
+
response: BrowserHttpResponse;
|
|
31
|
+
constructor(response: BrowserHttpResponse, message?: string | undefined);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Combine an external `signal` with an internal `timeout`-driven
|
|
35
|
+
* AbortController so either can cancel the in-flight fetch.
|
|
36
|
+
*/
|
|
37
|
+
export declare function combineSignals(external: AbortSignal | undefined, timeoutMs: number | undefined): {
|
|
38
|
+
signal: AbortSignal | undefined;
|
|
39
|
+
cleanup: () => void;
|
|
40
|
+
};
|
|
41
|
+
export declare function attempt(url: string, options: BrowserHttpRequestOptions): Promise<BrowserHttpResponse>;
|
|
42
|
+
export declare function decodeText(bytes: Uint8Array): string;
|
|
43
|
+
/**
|
|
44
|
+
* Per-attempt request info passed to `hooks.onRequest`. Mirrors the Node-side
|
|
45
|
+
* `HttpHookRequestInfo` shape so callers can share hook implementations.
|
|
46
|
+
*/
|
|
47
|
+
export interface BrowserHttpHookRequestInfo {
|
|
48
|
+
method: string;
|
|
49
|
+
url: string;
|
|
50
|
+
headers?: Record<string, string> | undefined;
|
|
51
|
+
timeout?: number | undefined;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Per-attempt response info passed to `hooks.onResponse`. Either `status`
|
|
55
|
+
* (success) or `error` (network failure) is populated.
|
|
56
|
+
*/
|
|
57
|
+
export interface BrowserHttpHookResponseInfo {
|
|
58
|
+
method: string;
|
|
59
|
+
url: string;
|
|
60
|
+
duration: number;
|
|
61
|
+
status?: number | undefined;
|
|
62
|
+
statusText?: string | undefined;
|
|
63
|
+
headers?: Record<string, string> | undefined;
|
|
64
|
+
error?: Error | undefined;
|
|
65
|
+
}
|
|
66
|
+
export interface BrowserHttpHooks {
|
|
67
|
+
onRequest?: ((info: BrowserHttpHookRequestInfo) => void) | undefined;
|
|
68
|
+
onResponse?: ((info: BrowserHttpHookResponseInfo) => void) | undefined;
|
|
69
|
+
}
|
|
70
|
+
export interface BrowserHttpRequestOptions {
|
|
71
|
+
/**
|
|
72
|
+
* Request body. Strings, Blobs, FormData, ArrayBuffer all pass through to
|
|
73
|
+
* fetch unchanged. Objects are NOT auto-stringified — the convenience wrapper
|
|
74
|
+
* `httpJson` handles JSON serialization.
|
|
75
|
+
*/
|
|
76
|
+
body?: string | Blob | FormData | ArrayBuffer | Uint8Array | undefined;
|
|
77
|
+
/**
|
|
78
|
+
* Whether to follow redirects automatically. Defaults to true (browser fetch
|
|
79
|
+
* default). Setting `false` sets `redirect: 'manual'` so 3xx responses are
|
|
80
|
+
* returned to the caller instead of followed.
|
|
81
|
+
*/
|
|
82
|
+
followRedirects?: boolean | undefined;
|
|
83
|
+
/**
|
|
84
|
+
* Request headers. Object form for ergonomics; passed through to fetch.
|
|
85
|
+
*/
|
|
86
|
+
headers?: Record<string, string> | undefined;
|
|
87
|
+
/**
|
|
88
|
+
* Lifecycle hooks for observing request/response events. Mirrors the
|
|
89
|
+
* Node-side `hooks` field. Hooks fire per-attempt — retries trigger separate
|
|
90
|
+
* hook calls.
|
|
91
|
+
*/
|
|
92
|
+
hooks?: BrowserHttpHooks | undefined;
|
|
93
|
+
/**
|
|
94
|
+
* Maximum response body size in bytes. Responses larger than this are
|
|
95
|
+
* truncated and treated as a network failure (so retries can fire). Defaults
|
|
96
|
+
* to no limit. Useful when calling untrusted endpoints.
|
|
97
|
+
*/
|
|
98
|
+
maxResponseSize?: number | undefined;
|
|
99
|
+
/**
|
|
100
|
+
* HTTP method. Defaults to GET.
|
|
101
|
+
*/
|
|
102
|
+
method?: string | undefined;
|
|
103
|
+
/**
|
|
104
|
+
* Number of retry attempts on 5xx / network failure. Defaults to 0 (no
|
|
105
|
+
* retries).
|
|
106
|
+
*/
|
|
107
|
+
retries?: number | undefined;
|
|
108
|
+
/**
|
|
109
|
+
* Base delay (ms) between retries. Doubles per attempt (exponential).
|
|
110
|
+
* Defaults to 250ms.
|
|
111
|
+
*/
|
|
112
|
+
retryDelay?: number | undefined;
|
|
113
|
+
/**
|
|
114
|
+
* Abort signal forwarded to fetch. Combined with `timeout` via
|
|
115
|
+
* AbortController when both are present.
|
|
116
|
+
*/
|
|
117
|
+
signal?: AbortSignal | undefined;
|
|
118
|
+
/**
|
|
119
|
+
* Throw on non-2xx response. Defaults to false; `httpJson` / `httpText` set
|
|
120
|
+
* this to true so callers don't have to check `.ok`.
|
|
121
|
+
*/
|
|
122
|
+
throwOnError?: boolean | undefined;
|
|
123
|
+
/**
|
|
124
|
+
* Per-attempt timeout in milliseconds. Implemented via AbortController;
|
|
125
|
+
* exceeds the timeout aborts the fetch and the attempt counts as a network
|
|
126
|
+
* failure (retryable). Defaults to no timeout (fetch defaults).
|
|
127
|
+
*/
|
|
128
|
+
timeout?: number | undefined;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Browser-shaped HTTP response. Surface mirrors the Node-side `HttpResponse`
|
|
132
|
+
* but with browser-native body types.
|
|
133
|
+
*/
|
|
134
|
+
export interface BrowserHttpResponse {
|
|
135
|
+
/**
|
|
136
|
+
* Raw response body. `Uint8Array` instead of Node's `Buffer`.
|
|
137
|
+
*/
|
|
138
|
+
body: Uint8Array;
|
|
139
|
+
/**
|
|
140
|
+
* Response headers, lowercased keys (matching Node side's lowercase
|
|
141
|
+
* convention). Repeated headers are joined with `, ` per fetch spec.
|
|
142
|
+
*/
|
|
143
|
+
headers: Record<string, string>;
|
|
144
|
+
/**
|
|
145
|
+
* Convenience: true when status is 2xx.
|
|
146
|
+
*/
|
|
147
|
+
ok: boolean;
|
|
148
|
+
/**
|
|
149
|
+
* HTTP status code.
|
|
150
|
+
*/
|
|
151
|
+
status: number;
|
|
152
|
+
/**
|
|
153
|
+
* HTTP status text.
|
|
154
|
+
*/
|
|
155
|
+
statusText: string;
|
|
156
|
+
/**
|
|
157
|
+
* Final URL after any redirects.
|
|
158
|
+
*/
|
|
159
|
+
url: string;
|
|
160
|
+
/**
|
|
161
|
+
* Body as ArrayBuffer.
|
|
162
|
+
*/
|
|
163
|
+
arrayBuffer(): ArrayBuffer;
|
|
164
|
+
/**
|
|
165
|
+
* Body parsed as JSON. Throws on invalid JSON.
|
|
166
|
+
*/
|
|
167
|
+
json<T = unknown>(): T;
|
|
168
|
+
/**
|
|
169
|
+
* Body decoded as UTF-8 text.
|
|
170
|
+
*/
|
|
171
|
+
text(): string;
|
|
172
|
+
}
|
|
173
|
+
export declare function headersToRecord(headers: Headers): Record<string, string>;
|
|
174
|
+
/**
|
|
175
|
+
* GET / POST a JSON endpoint. Automatically sets `Accept: application/json` and
|
|
176
|
+
* `Content-Type: application/json` (when a body is present). Throws
|
|
177
|
+
* `HttpResponseError` on non-2xx.
|
|
178
|
+
*/
|
|
179
|
+
export declare function httpJson<T = unknown>(url: string, options?: BrowserHttpRequestOptions | undefined): Promise<T>;
|
|
180
|
+
/**
|
|
181
|
+
* Lower-level HTTP request. Use `httpJson` / `httpText` for the common cases.
|
|
182
|
+
* Returns the response unconditionally — callers inspect `.ok` or pass
|
|
183
|
+
* `throwOnError: true` to get a thrown `HttpResponseError` on non-2xx.
|
|
184
|
+
*/
|
|
185
|
+
export declare function httpRequest(url: string, options?: BrowserHttpRequestOptions | undefined): Promise<BrowserHttpResponse>;
|
|
186
|
+
/**
|
|
187
|
+
* GET / POST a text endpoint. Throws `HttpResponseError` on non-2xx.
|
|
188
|
+
*/
|
|
189
|
+
export declare function httpText(url: string, options?: BrowserHttpRequestOptions | undefined): Promise<string>;
|
|
190
|
+
export declare function sleep(ms: number): Promise<void>;
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Socket Lib - Built with esbuild */
|
|
3
|
+
"use strict";
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
21
|
+
var browser_exports = {};
|
|
22
|
+
__export(browser_exports, {
|
|
23
|
+
HttpResponseError: () => HttpResponseError,
|
|
24
|
+
attempt: () => attempt,
|
|
25
|
+
combineSignals: () => combineSignals,
|
|
26
|
+
decodeText: () => decodeText,
|
|
27
|
+
headersToRecord: () => headersToRecord,
|
|
28
|
+
httpJson: () => httpJson,
|
|
29
|
+
httpRequest: () => httpRequest,
|
|
30
|
+
httpText: () => httpText,
|
|
31
|
+
sleep: () => sleep
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(browser_exports);
|
|
34
|
+
var import_browser_fetch = require("./browser-fetch");
|
|
35
|
+
class HttpResponseError extends Error {
|
|
36
|
+
response;
|
|
37
|
+
constructor(response, message) {
|
|
38
|
+
const statusCode = response.status ?? "unknown";
|
|
39
|
+
const statusMessage = response.statusText || "No status message";
|
|
40
|
+
super(message ?? `HTTP ${statusCode}: ${statusMessage}`);
|
|
41
|
+
this.name = "HttpResponseError";
|
|
42
|
+
this.response = response;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function combineSignals(external, timeoutMs) {
|
|
46
|
+
if (!timeoutMs) {
|
|
47
|
+
return { signal: external, cleanup: () => {
|
|
48
|
+
} };
|
|
49
|
+
}
|
|
50
|
+
const controller = new AbortController();
|
|
51
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
52
|
+
let externalListener;
|
|
53
|
+
if (external) {
|
|
54
|
+
if (external.aborted) {
|
|
55
|
+
controller.abort();
|
|
56
|
+
} else {
|
|
57
|
+
externalListener = () => controller.abort();
|
|
58
|
+
external.addEventListener("abort", externalListener);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
signal: controller.signal,
|
|
63
|
+
cleanup: () => {
|
|
64
|
+
clearTimeout(timer);
|
|
65
|
+
if (external && externalListener) {
|
|
66
|
+
external.removeEventListener("abort", externalListener);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
async function attempt(url, options) {
|
|
72
|
+
const method = options.method ?? "GET";
|
|
73
|
+
const init = { method };
|
|
74
|
+
if (options.headers) {
|
|
75
|
+
init.headers = options.headers;
|
|
76
|
+
}
|
|
77
|
+
if (options.body !== void 0) {
|
|
78
|
+
;
|
|
79
|
+
init.body = options.body;
|
|
80
|
+
}
|
|
81
|
+
if (options.followRedirects === false) {
|
|
82
|
+
init.redirect = "manual";
|
|
83
|
+
}
|
|
84
|
+
const { signal, cleanup } = combineSignals(options.signal, options.timeout);
|
|
85
|
+
if (signal) {
|
|
86
|
+
init.signal = signal;
|
|
87
|
+
}
|
|
88
|
+
const startedAt = Date.now();
|
|
89
|
+
if (options.hooks?.onRequest) {
|
|
90
|
+
options.hooks.onRequest({
|
|
91
|
+
method,
|
|
92
|
+
url,
|
|
93
|
+
headers: options.headers,
|
|
94
|
+
timeout: options.timeout
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
const response = await (0, import_browser_fetch.doFetch)(url, init);
|
|
99
|
+
const buffer = await response.arrayBuffer();
|
|
100
|
+
if (options.maxResponseSize !== void 0 && buffer.byteLength > options.maxResponseSize) {
|
|
101
|
+
throw new Error(
|
|
102
|
+
`Response body (${buffer.byteLength} bytes) exceeds maxResponseSize (${options.maxResponseSize})`
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
const body = new Uint8Array(buffer);
|
|
106
|
+
const headers = headersToRecord(response.headers);
|
|
107
|
+
if (options.hooks?.onResponse) {
|
|
108
|
+
options.hooks.onResponse({
|
|
109
|
+
method,
|
|
110
|
+
url,
|
|
111
|
+
duration: Date.now() - startedAt,
|
|
112
|
+
status: response.status,
|
|
113
|
+
statusText: response.statusText,
|
|
114
|
+
headers
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
body,
|
|
119
|
+
headers,
|
|
120
|
+
status: response.status,
|
|
121
|
+
statusText: response.statusText,
|
|
122
|
+
ok: response.ok,
|
|
123
|
+
url: response.url,
|
|
124
|
+
arrayBuffer() {
|
|
125
|
+
return buffer;
|
|
126
|
+
},
|
|
127
|
+
text() {
|
|
128
|
+
return decodeText(body);
|
|
129
|
+
},
|
|
130
|
+
json() {
|
|
131
|
+
return JSON.parse(decodeText(body));
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
} catch (err) {
|
|
135
|
+
if (options.hooks?.onResponse) {
|
|
136
|
+
options.hooks.onResponse({
|
|
137
|
+
method,
|
|
138
|
+
url,
|
|
139
|
+
duration: Date.now() - startedAt,
|
|
140
|
+
error: err instanceof Error ? err : new Error(String(err))
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
throw err;
|
|
144
|
+
} finally {
|
|
145
|
+
cleanup();
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
function decodeText(bytes) {
|
|
149
|
+
return new TextDecoder("utf-8").decode(bytes);
|
|
150
|
+
}
|
|
151
|
+
function headersToRecord(headers) {
|
|
152
|
+
const out = {};
|
|
153
|
+
headers.forEach((value, key) => {
|
|
154
|
+
out[key.toLowerCase()] = value;
|
|
155
|
+
});
|
|
156
|
+
return out;
|
|
157
|
+
}
|
|
158
|
+
async function httpJson(url, options) {
|
|
159
|
+
const opts = options ?? {};
|
|
160
|
+
const headers = {
|
|
161
|
+
Accept: "application/json",
|
|
162
|
+
...opts.headers ?? {}
|
|
163
|
+
};
|
|
164
|
+
if (opts.body !== void 0 && !("Content-Type" in headers)) {
|
|
165
|
+
headers["Content-Type"] = "application/json";
|
|
166
|
+
}
|
|
167
|
+
const response = await httpRequest(url, {
|
|
168
|
+
...opts,
|
|
169
|
+
headers,
|
|
170
|
+
throwOnError: true
|
|
171
|
+
});
|
|
172
|
+
return response.json();
|
|
173
|
+
}
|
|
174
|
+
async function httpRequest(url, options) {
|
|
175
|
+
const opts = options ?? {};
|
|
176
|
+
const maxAttempts = (opts.retries ?? 0) + 1;
|
|
177
|
+
const baseDelay = opts.retryDelay ?? 250;
|
|
178
|
+
let lastError;
|
|
179
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
180
|
+
try {
|
|
181
|
+
const response = await attempt(url, opts);
|
|
182
|
+
if (response.status >= 500 && i + 1 < maxAttempts) {
|
|
183
|
+
await sleep(baseDelay * Math.pow(2, i));
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
if (opts.throwOnError && !response.ok) {
|
|
187
|
+
throw new HttpResponseError(response);
|
|
188
|
+
}
|
|
189
|
+
return response;
|
|
190
|
+
} catch (err) {
|
|
191
|
+
lastError = err;
|
|
192
|
+
if (err instanceof HttpResponseError) {
|
|
193
|
+
throw err;
|
|
194
|
+
}
|
|
195
|
+
if (i + 1 < maxAttempts) {
|
|
196
|
+
await sleep(baseDelay * Math.pow(2, i));
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
throw lastError instanceof Error ? lastError : new Error(`HTTP request to ${url} failed`);
|
|
202
|
+
}
|
|
203
|
+
async function httpText(url, options) {
|
|
204
|
+
const response = await httpRequest(url, {
|
|
205
|
+
...options ?? {},
|
|
206
|
+
throwOnError: true
|
|
207
|
+
});
|
|
208
|
+
return response.text();
|
|
209
|
+
}
|
|
210
|
+
function sleep(ms) {
|
|
211
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
212
|
+
}
|
|
213
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
214
|
+
0 && (module.exports = {
|
|
215
|
+
HttpResponseError,
|
|
216
|
+
attempt,
|
|
217
|
+
combineSignals,
|
|
218
|
+
decodeText,
|
|
219
|
+
headersToRecord,
|
|
220
|
+
httpJson,
|
|
221
|
+
httpRequest,
|
|
222
|
+
httpText,
|
|
223
|
+
sleep
|
|
224
|
+
});
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* - `Checksums` / `FetchChecksumsOptions` — checksum-file helpers
|
|
7
7
|
*/
|
|
8
8
|
import type { IncomingHttpHeaders } from 'node:http';
|
|
9
|
-
import type { Logger } from '../logger/
|
|
9
|
+
import type { Logger } from '../logger/node';
|
|
10
10
|
/**
|
|
11
11
|
* Configuration options for file downloads.
|
|
12
12
|
*/
|
|
@@ -55,7 +55,7 @@ export interface HttpDownloadOptions {
|
|
|
55
55
|
*
|
|
56
56
|
* @example
|
|
57
57
|
* ;```ts
|
|
58
|
-
* import { getDefaultLogger } from '@socketsecurity/lib/logger/
|
|
58
|
+
* import { getDefaultLogger } from '@socketsecurity/lib/logger/node'
|
|
59
59
|
*
|
|
60
60
|
* const logger = getDefaultLogger()
|
|
61
61
|
* await httpDownload('https://example.com/file.zip', '/tmp/file.zip', {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Public HTTP-request entry — re-exports the platform-correct
|
|
3
|
+
* implementation. Bundlers that honor the package.json `'browser'` condition
|
|
4
|
+
* (rolldown, vite, esbuild on browser platform) swap this entry to
|
|
5
|
+
* `./browser`; Node consumers get `./node`. Same named exports (`httpJson`,
|
|
6
|
+
* `httpText`, `httpRequest`, `HttpResponseError`) on both platforms so
|
|
7
|
+
* callers can write `import { httpJson } from
|
|
8
|
+
* '@socketsecurity/lib/http-request/http-request'` without caring about
|
|
9
|
+
* platform.
|
|
10
|
+
*/
|
|
11
|
+
export { httpJson, httpRequest, httpText, HttpResponseError } from './node';
|
|
12
|
+
export type { HttpResponse, HttpRequestOptions } from './node';
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* Socket Lib - Built with esbuild */
|
|
3
|
+
"use strict";
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
21
|
+
var http_request_exports = {};
|
|
22
|
+
__export(http_request_exports, {
|
|
23
|
+
HttpResponseError: () => import_node.HttpResponseError,
|
|
24
|
+
httpJson: () => import_node.httpJson,
|
|
25
|
+
httpRequest: () => import_node.httpRequest,
|
|
26
|
+
httpText: () => import_node.httpText
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(http_request_exports);
|
|
29
|
+
var import_node = require("./node");
|
|
30
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
31
|
+
0 && (module.exports = {
|
|
32
|
+
HttpResponseError,
|
|
33
|
+
httpJson,
|
|
34
|
+
httpRequest,
|
|
35
|
+
httpText
|
|
36
|
+
});
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Node-side HTTP request layer — the public surface (`httpJson`,
|
|
3
|
+
* `httpText`, `httpRequest`, `HttpResponseError`) for consumers on Node.
|
|
4
|
+
* Pairs with `./browser` (browser-safe variant via `fetch`); both files
|
|
5
|
+
* expose the same named exports so the package.json `'browser'` condition can
|
|
6
|
+
* swap them by platform without consumers changing their imports. `httpJson`
|
|
7
|
+
* and `httpText` live here directly; `httpRequest` and the shared types are
|
|
8
|
+
* re-exported from their dedicated leaves so the sub-imports
|
|
9
|
+
* (`./http-request/request`, `./http-request/response-types`) stay loadable
|
|
10
|
+
* individually for callers that don't want the convenience wrappers in their
|
|
11
|
+
* bundle.
|
|
12
|
+
*/
|
|
13
|
+
import type { HttpRequestOptions } from './request-types';
|
|
14
|
+
export { httpRequest } from './request';
|
|
15
|
+
export { HttpResponseError } from './response-types';
|
|
16
|
+
export type { HttpResponse } from './response-types';
|
|
17
|
+
export type { HttpRequestOptions } from './request-types';
|
|
18
|
+
/**
|
|
19
|
+
* GET / POST a JSON endpoint. Automatically sets `Accept: application/json` and
|
|
20
|
+
* `Content-Type: application/json` (when a body is present); user-supplied
|
|
21
|
+
* headers always win. Throws `HttpResponseError` on non-2xx.
|
|
22
|
+
*/
|
|
23
|
+
export declare function httpJson<T = unknown>(url: string, options?: HttpRequestOptions | undefined): Promise<T>;
|
|
24
|
+
/**
|
|
25
|
+
* GET / POST a text endpoint. Sets `Accept: text/plain` (and `Content-Type:
|
|
26
|
+
* text/plain` on bodies); user headers override. Throws `HttpResponseError` on
|
|
27
|
+
* non-2xx.
|
|
28
|
+
*/
|
|
29
|
+
export declare function httpText(url: string, options?: HttpRequestOptions | undefined): Promise<string>;
|
|
@@ -18,15 +18,19 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
return to;
|
|
19
19
|
};
|
|
20
20
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
21
|
-
var
|
|
22
|
-
__export(
|
|
21
|
+
var node_exports = {};
|
|
22
|
+
__export(node_exports, {
|
|
23
|
+
HttpResponseError: () => import_response_types2.HttpResponseError,
|
|
23
24
|
httpJson: () => httpJson,
|
|
25
|
+
httpRequest: () => import_request2.httpRequest,
|
|
24
26
|
httpText: () => httpText
|
|
25
27
|
});
|
|
26
|
-
module.exports = __toCommonJS(
|
|
28
|
+
module.exports = __toCommonJS(node_exports);
|
|
27
29
|
var import_error = require("../primordials/error");
|
|
28
30
|
var import_request = require("./request");
|
|
29
31
|
var import_response_types = require("./response-types");
|
|
32
|
+
var import_request2 = require("./request");
|
|
33
|
+
var import_response_types2 = require("./response-types");
|
|
30
34
|
async function httpJson(url, options) {
|
|
31
35
|
const {
|
|
32
36
|
body,
|
|
@@ -91,6 +95,8 @@ async function httpText(url, options) {
|
|
|
91
95
|
}
|
|
92
96
|
// Annotate the CommonJS export names for ESM import in node:
|
|
93
97
|
0 && (module.exports = {
|
|
98
|
+
HttpResponseError,
|
|
94
99
|
httpJson,
|
|
100
|
+
httpRequest,
|
|
95
101
|
httpText
|
|
96
102
|
});
|
|
@@ -42,6 +42,7 @@ async function httpRequestAttempt(url, options) {
|
|
|
42
42
|
maxRedirects = 5,
|
|
43
43
|
maxResponseSize,
|
|
44
44
|
method = "GET",
|
|
45
|
+
signal,
|
|
45
46
|
stream = false,
|
|
46
47
|
timeout = 3e4
|
|
47
48
|
} = { __proto__: null, ...options };
|
|
@@ -88,6 +89,9 @@ async function httpRequestAttempt(url, options) {
|
|
|
88
89
|
if (ca && isHttps) {
|
|
89
90
|
requestOptions["ca"] = ca;
|
|
90
91
|
}
|
|
92
|
+
if (signal) {
|
|
93
|
+
requestOptions["signal"] = signal;
|
|
94
|
+
}
|
|
91
95
|
const emitResponse = (info) => {
|
|
92
96
|
try {
|
|
93
97
|
hooks?.onResponse?.({
|
|
@@ -206,6 +206,21 @@ export interface HttpRequestOptions {
|
|
|
206
206
|
* @default 1000
|
|
207
207
|
*/
|
|
208
208
|
retryDelay?: number | undefined;
|
|
209
|
+
/**
|
|
210
|
+
* AbortSignal forwarded to the underlying `http.request` / `https.request`
|
|
211
|
+
* call. Supported in Node 22+ via `node:http` request options. When both
|
|
212
|
+
* `signal` and `timeout` are provided, either can cancel the in-flight
|
|
213
|
+
* request (whichever fires first). Aborts are NOT retried — an external
|
|
214
|
+
* cancel is treated as an explicit caller decision.
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ;```ts
|
|
218
|
+
* const ac = new AbortController()
|
|
219
|
+
* setTimeout(() => ac.abort(), 5000)
|
|
220
|
+
* await httpRequest('https://api.example.com/x', { signal: ac.signal })
|
|
221
|
+
* ```
|
|
222
|
+
*/
|
|
223
|
+
signal?: AbortSignal | undefined;
|
|
209
224
|
/**
|
|
210
225
|
* When true, resolve with an HttpResponse whose body is NOT buffered. The
|
|
211
226
|
* `rawResponse` property contains the unconsumed IncomingResponse stream for
|
|
@@ -46,6 +46,7 @@ async function httpRequest(url, options) {
|
|
|
46
46
|
onRetry,
|
|
47
47
|
retries = 0,
|
|
48
48
|
retryDelay = 1e3,
|
|
49
|
+
signal,
|
|
49
50
|
stream = false,
|
|
50
51
|
throwOnError = false,
|
|
51
52
|
timeout = 3e4
|
|
@@ -67,6 +68,7 @@ async function httpRequest(url, options) {
|
|
|
67
68
|
maxRedirects,
|
|
68
69
|
maxResponseSize,
|
|
69
70
|
method,
|
|
71
|
+
signal,
|
|
70
72
|
stream,
|
|
71
73
|
timeout
|
|
72
74
|
};
|
|
@@ -83,6 +85,9 @@ async function httpRequest(url, options) {
|
|
|
83
85
|
if (attempt === retries) {
|
|
84
86
|
break;
|
|
85
87
|
}
|
|
88
|
+
if (signal?.aborted) {
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
86
91
|
const delayMs = retryDelay * 2 ** attempt;
|
|
87
92
|
if (onRetry) {
|
|
88
93
|
const retryResult = onRetry(attempt + 1, e, delayMs);
|
|
@@ -13,7 +13,7 @@ import type { LinkOptions } from './types';
|
|
|
13
13
|
*
|
|
14
14
|
* @example
|
|
15
15
|
* ;```ts
|
|
16
|
-
* import { link } from '@socketsecurity/lib/links/
|
|
16
|
+
* import { link } from '@socketsecurity/lib/links/create'
|
|
17
17
|
*
|
|
18
18
|
* // Use current theme
|
|
19
19
|
* console.log(link('Documentation', 'https://socket.dev'))
|
|
@@ -46,7 +46,7 @@ export declare function link(text: string, url: string, options?: LinkOptions):
|
|
|
46
46
|
*
|
|
47
47
|
* @example
|
|
48
48
|
* ;```ts
|
|
49
|
-
* import { links } from '@socketsecurity/lib/links/
|
|
49
|
+
* import { links } from '@socketsecurity/lib/links/create'
|
|
50
50
|
*
|
|
51
51
|
* const formatted = links([
|
|
52
52
|
* ['Documentation', 'https://socket.dev'],
|
|
@@ -28,12 +28,12 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
28
28
|
mod
|
|
29
29
|
));
|
|
30
30
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
31
|
-
var
|
|
32
|
-
__export(
|
|
31
|
+
var create_exports = {};
|
|
32
|
+
__export(create_exports, {
|
|
33
33
|
link: () => link,
|
|
34
34
|
links: () => links
|
|
35
35
|
});
|
|
36
|
-
module.exports = __toCommonJS(
|
|
36
|
+
module.exports = __toCommonJS(create_exports);
|
|
37
37
|
var import_yoctocolors_cjs = __toESM(require("../external/yoctocolors-cjs"));
|
|
38
38
|
var import_array = require("../primordials/array");
|
|
39
39
|
var import_context = require("../themes/context");
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @file Private state shared between the `logger/
|
|
2
|
+
* @file Private state shared between the `logger/node` class (which owns the
|
|
3
3
|
* public `Logger` surface) and `logger/console-init` (which mutates
|
|
4
4
|
* `Logger.prototype` to mirror `globalConsole`). The `_` prefix keeps this
|
|
5
5
|
* module out of the generated package.json `exports` map (the `dist/**\/_*`
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Browser-safe `Logger` implementation — mirrors the public `success` /
|
|
3
|
+
* `fail` / `warn` / `error` / `info` / `log` surface of the Node `Logger`
|
|
4
|
+
* (see `./node`) but backed by the global `console` so it works in Chrome MV3
|
|
5
|
+
* service workers, content scripts, popups, and any other browser context
|
|
6
|
+
* without `node:process` / `node:console` / fs. Consumers should import
|
|
7
|
+
* `Logger` from `./logger` (auto-routed by the package.json `browser`
|
|
8
|
+
* condition) or `./default` for the singleton. `./browser` is the
|
|
9
|
+
* explicit-platform name; useful for tests pinning to one implementation.
|
|
10
|
+
*/
|
|
11
|
+
export declare class Logger {
|
|
12
|
+
log(message: unknown, ...args: unknown[]): this;
|
|
13
|
+
info(message: unknown, ...args: unknown[]): this;
|
|
14
|
+
warn(message: unknown, ...args: unknown[]): this;
|
|
15
|
+
error(message: unknown, ...args: unknown[]): this;
|
|
16
|
+
success(message: unknown, ...args: unknown[]): this;
|
|
17
|
+
fail(message: unknown, ...args: unknown[]): this;
|
|
18
|
+
}
|