@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.
Files changed (135) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/README.md +26 -17
  3. package/dist/ai/discover.js +2 -2
  4. package/dist/ai/spawn.js +3 -3
  5. package/dist/ai/worktree.js +3 -3
  6. package/dist/argv/parse-args-string.d.ts +30 -0
  7. package/dist/argv/parse-args-string.js +42 -0
  8. package/dist/bin/check-primordials.js +15 -10
  9. package/dist/bin/check.js +2 -2
  10. package/dist/bin/exec.d.ts +1 -1
  11. package/dist/bin/exec.js +2 -2
  12. package/dist/bin/socket-lib.js +2 -2
  13. package/dist/{ttl-cache/cache.js → cache/ttl/store.js} +15 -15
  14. package/dist/{ttl-cache → cache/ttl}/types.d.ts +1 -1
  15. package/dist/checks/primordials-defaults.d.ts +20 -0
  16. package/dist/checks/primordials-defaults.js +92 -0
  17. package/dist/colors/socket-palette.d.ts +69 -0
  18. package/dist/colors/socket-palette.js +91 -0
  19. package/dist/constants/socket.js +1 -1
  20. package/dist/cover/code.js +2 -2
  21. package/dist/cover/type.js +2 -2
  22. package/dist/debug/_internal.d.ts +1 -1
  23. package/dist/debug/_internal.js +2 -2
  24. package/dist/debug/output.js +5 -5
  25. package/dist/dlx/binary-types.d.ts +2 -2
  26. package/dist/dlx/binary.d.ts +2 -2
  27. package/dist/dlx/binary.js +3 -3
  28. package/dist/dlx/firewall.js +2 -2
  29. package/dist/dlx/manifest.js +2 -2
  30. package/dist/dlx/package.d.ts +2 -2
  31. package/dist/dlx/package.js +2 -2
  32. package/dist/dlx/types.d.ts +2 -2
  33. package/dist/eco/npm/npm/exec.d.ts +2 -2
  34. package/dist/eco/npm/npm/exec.js +2 -2
  35. package/dist/eco/npm/pnpm/exec.d.ts +1 -1
  36. package/dist/eco/npm/script.d.ts +1 -1
  37. package/dist/eco/npm/script.js +3 -3
  38. package/dist/eco/npm/yarnpkg/yarn/exec.d.ts +1 -1
  39. package/dist/{signal-exit → events/exit}/_internal.d.ts +1 -1
  40. package/dist/{signal-exit/register.js → events/exit/handler.js} +4 -4
  41. package/dist/{signal-exit → events/exit}/intercept.js +2 -2
  42. package/dist/{signal-exit → events/exit}/types.d.ts +1 -1
  43. package/dist/{warnings/event-target.d.ts → events/warning/handler.d.ts} +1 -1
  44. package/dist/{warnings/event-target.js → events/warning/handler.js} +4 -4
  45. package/dist/{warnings → events/warning}/suppress.d.ts +3 -3
  46. package/dist/{warnings → events/warning}/suppress.js +2 -2
  47. package/dist/external-tools/janus/asset-names.d.ts +7 -0
  48. package/dist/external-tools/janus/asset-names.js +5 -0
  49. package/dist/external-tools/janus/from-download.d.ts +1 -1
  50. package/dist/external-tools/janus/from-download.js +12 -4
  51. package/dist/fs/read-json-cache.d.ts +83 -0
  52. package/dist/fs/read-json-cache.js +156 -0
  53. package/dist/fs/read-json.d.ts +6 -1
  54. package/dist/fs/read-json.js +80 -8
  55. package/dist/fs/types.d.ts +14 -0
  56. package/dist/git/_internal.js +3 -3
  57. package/dist/github/refs-cache.d.ts +1 -1
  58. package/dist/github/refs-cache.js +2 -2
  59. package/dist/github/token.d.ts +1 -1
  60. package/dist/github/token.js +2 -2
  61. package/dist/globs/{glob.js → match.js} +3 -3
  62. package/dist/http-request/browser-fetch.d.ts +10 -0
  63. package/dist/http-request/browser-fetch.js +32 -0
  64. package/dist/http-request/browser.d.ts +190 -0
  65. package/dist/http-request/browser.js +224 -0
  66. package/dist/http-request/download-types.d.ts +2 -2
  67. package/dist/http-request/http-request.d.ts +12 -0
  68. package/dist/http-request/http-request.js +36 -0
  69. package/dist/http-request/node.d.ts +29 -0
  70. package/dist/http-request/{convenience.js → node.js} +9 -3
  71. package/dist/http-request/request-attempt.js +4 -0
  72. package/dist/http-request/request-types.d.ts +15 -0
  73. package/dist/http-request/request.js +5 -0
  74. package/dist/links/{link.d.ts → create.d.ts} +2 -2
  75. package/dist/links/{link.js → create.js} +3 -3
  76. package/dist/logger/_internal.d.ts +1 -1
  77. package/dist/logger/browser.d.ts +18 -0
  78. package/dist/logger/browser.js +58 -0
  79. package/dist/logger/console.js +3 -3
  80. package/dist/logger/default.d.ts +11 -0
  81. package/dist/logger/default.js +37 -0
  82. package/dist/logger/logger.d.ts +8 -403
  83. package/dist/logger/logger.js +3 -827
  84. package/dist/logger/node.d.ts +400 -0
  85. package/dist/logger/node.js +856 -0
  86. package/dist/logger/symbols-builder.d.ts +1 -1
  87. package/dist/logger/types.d.ts +1 -1
  88. package/dist/packages/isolation.js +3 -3
  89. package/dist/packages/provenance.d.ts +42 -0
  90. package/dist/packages/provenance.js +71 -0
  91. package/dist/packages/types.d.ts +2 -0
  92. package/dist/primordials/globals.d.ts +6 -3
  93. package/dist/primordials/globals.js +15 -9
  94. package/dist/primordials/map-set.d.ts +35 -0
  95. package/dist/primordials/map-set.js +43 -0
  96. package/dist/primordials/url.d.ts +1 -1
  97. package/dist/process/lock-manager.js +4 -4
  98. package/dist/{spawn → process/spawn}/_internal.js +3 -3
  99. package/dist/{spawn/spawn.js → process/spawn/child.js} +13 -13
  100. package/dist/{spawn → process/spawn}/errors.js +5 -5
  101. package/dist/{spawn → process/spawn}/stdio.js +1 -1
  102. package/dist/{spawn → process/spawn}/types.d.ts +3 -3
  103. package/dist/promises/types.d.ts +15 -2
  104. package/dist/releases/github-archives.js +2 -2
  105. package/dist/releases/github-downloads.js +4 -4
  106. package/dist/spinner/{registry.d.ts → default.d.ts} +1 -1
  107. package/dist/spinner/{registry.js → default.js} +3 -3
  108. package/dist/spinner/spinner.js +4 -4
  109. package/dist/spinner/with.d.ts +1 -1
  110. package/dist/stdio/divider.js +2 -2
  111. package/dist/stdio/footer.js +2 -2
  112. package/dist/stdio/header.js +2 -2
  113. package/dist/stdio/prompts.js +2 -2
  114. package/package.json +410 -132
  115. package/dist/http-request/convenience.d.ts +0 -104
  116. package/dist/promise-queue/types.d.ts +0 -10
  117. package/dist/ttl-cache/types.js +0 -18
  118. /package/dist/{ttl-cache/cache.d.ts → cache/ttl/store.d.ts} +0 -0
  119. /package/dist/{promise-queue → cache/ttl}/types.js +0 -0
  120. /package/dist/{signal-exit → events/exit}/_internal.js +0 -0
  121. /package/dist/{signal-exit/register.d.ts → events/exit/handler.d.ts} +0 -0
  122. /package/dist/{signal-exit → events/exit}/intercept.d.ts +0 -0
  123. /package/dist/{signal-exit → events/exit}/lifecycle.d.ts +0 -0
  124. /package/dist/{signal-exit → events/exit}/lifecycle.js +0 -0
  125. /package/dist/{signal-exit → events/exit}/signals.d.ts +0 -0
  126. /package/dist/{signal-exit → events/exit}/signals.js +0 -0
  127. /package/dist/{signal-exit → events/exit}/types.js +0 -0
  128. /package/dist/globs/{glob.d.ts → match.d.ts} +0 -0
  129. /package/dist/{spawn → process/spawn}/_internal.d.ts +0 -0
  130. /package/dist/{spawn/spawn.d.ts → process/spawn/child.d.ts} +0 -0
  131. /package/dist/{spawn → process/spawn}/errors.d.ts +0 -0
  132. /package/dist/{spawn → process/spawn}/stdio.d.ts +0 -0
  133. /package/dist/{spawn → process/spawn}/types.js +0 -0
  134. /package/dist/{promise-queue → promises}/queue.d.ts +0 -0
  135. /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/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/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 convenience_exports = {};
22
- __export(convenience_exports, {
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(convenience_exports);
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/link'
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/link'
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 link_exports = {};
32
- __export(link_exports, {
31
+ var create_exports = {};
32
+ __export(create_exports, {
33
33
  link: () => link,
34
34
  links: () => links
35
35
  });
36
- module.exports = __toCommonJS(link_exports);
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/logger` class (which owns the
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
+ }