@harborclient/http 0.1.1
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/LICENSE +21 -0
- package/README.md +34 -0
- package/dist/Body.d.ts +28 -0
- package/dist/Body.d.ts.map +1 -0
- package/dist/Body.js +72 -0
- package/dist/Headers.d.ts +25 -0
- package/dist/Headers.d.ts.map +1 -0
- package/dist/Headers.js +62 -0
- package/dist/IBody.d.ts +32 -0
- package/dist/IBody.d.ts.map +1 -0
- package/dist/IBody.js +1 -0
- package/dist/IHeaders.d.ts +40 -0
- package/dist/IHeaders.d.ts.map +1 -0
- package/dist/IHeaders.js +1 -0
- package/dist/IQueryString.d.ts +20 -0
- package/dist/IQueryString.d.ts.map +1 -0
- package/dist/IQueryString.js +1 -0
- package/dist/IRequester.d.ts +17 -0
- package/dist/IRequester.d.ts.map +1 -0
- package/dist/IRequester.js +1 -0
- package/dist/IResponseReader.d.ts +29 -0
- package/dist/IResponseReader.d.ts.map +1 -0
- package/dist/IResponseReader.js +1 -0
- package/dist/QueryString.d.ts +40 -0
- package/dist/QueryString.d.ts.map +1 -0
- package/dist/QueryString.js +78 -0
- package/dist/Requester.d.ts +100 -0
- package/dist/Requester.d.ts.map +1 -0
- package/dist/Requester.js +403 -0
- package/dist/ResponseReader.d.ts +24 -0
- package/dist/ResponseReader.d.ts.map +1 -0
- package/dist/ResponseReader.js +66 -0
- package/dist/formData.d.ts +27 -0
- package/dist/formData.d.ts.map +1 -0
- package/dist/formData.js +58 -0
- package/dist/httpHeaders.d.ts +23 -0
- package/dist/httpHeaders.d.ts.map +1 -0
- package/dist/httpHeaders.js +61 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/logger.d.ts +19 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +34 -0
- package/dist/settings.d.ts +42 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +26 -0
- package/dist/types.d.ts +231 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/urlencoded.d.ts +27 -0
- package/dist/urlencoded.d.ts.map +1 -0
- package/dist/urlencoded.js +53 -0
- package/package.json +101 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export { HARD_MAX_RESPONSE_SIZE_MB, DEFAULT_PROXY_SETTINGS, DEFAULT_REQUEST_SETTINGS } from './settings.js';
|
|
2
|
+
export type { RequestSettings } from './settings.js';
|
|
3
|
+
export type { ApplyCookieResult, BuildHeadersResult } from './IHeaders.js';
|
|
4
|
+
export type { BuildMultipartResult } from './IBody.js';
|
|
5
|
+
export type { ReadResponseBodyResult } from './IResponseReader.js';
|
|
6
|
+
export type { IBody } from './IBody.js';
|
|
7
|
+
export type { IHeaders } from './IHeaders.js';
|
|
8
|
+
export type { IQueryString } from './IQueryString.js';
|
|
9
|
+
export type { IRequester } from './IRequester.js';
|
|
10
|
+
export type { IResponseReader } from './IResponseReader.js';
|
|
11
|
+
export type { RequesterDeps } from './Requester.js';
|
|
12
|
+
export type { BodyType, FormDataPart, FormDataPartType, HttpMethod, KeyValue, ProxyProtocol, ProxySettings, RedirectHop, SendRequestInput, SendResult, SentRequest } from './types.js';
|
|
13
|
+
export { Body } from './Body.js';
|
|
14
|
+
export { Headers } from './Headers.js';
|
|
15
|
+
export { QueryString } from './QueryString.js';
|
|
16
|
+
export { MAX_REDIRECTS, REDIRECT_STATUSES, Requester } from './Requester.js';
|
|
17
|
+
export { ResponseReader } from './ResponseReader.js';
|
|
18
|
+
export { emptyFormPart, normalizeFormPart, parseFormParts, serializeFormParts } from './formData.js';
|
|
19
|
+
export { emptyUrlEncodedPart, normalizeUrlEncodedPart, parseUrlEncodedParts, serializeUrlEncodedParts } from './urlencoded.js';
|
|
20
|
+
export { hasUnsafeHeaderFieldChars, validateHeaderField, validateHeaders } from './httpHeaders.js';
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EACtB,wBAAwB,EACzB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAC3E,YAAY,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvD,YAAY,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACnE,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,gBAAgB,EAChB,UAAU,EACV,QAAQ,EACR,aAAa,EACb,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,UAAU,EACV,WAAW,EACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,mBAAmB,EACnB,uBAAuB,EACvB,oBAAoB,EACpB,wBAAwB,EACzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { HARD_MAX_RESPONSE_SIZE_MB, DEFAULT_PROXY_SETTINGS, DEFAULT_REQUEST_SETTINGS } from './settings.js';
|
|
2
|
+
export { Body } from './Body.js';
|
|
3
|
+
export { Headers } from './Headers.js';
|
|
4
|
+
export { QueryString } from './QueryString.js';
|
|
5
|
+
export { MAX_REDIRECTS, REDIRECT_STATUSES, Requester } from './Requester.js';
|
|
6
|
+
export { ResponseReader } from './ResponseReader.js';
|
|
7
|
+
export { emptyFormPart, normalizeFormPart, parseFormParts, serializeFormParts } from './formData.js';
|
|
8
|
+
export { emptyUrlEncodedPart, normalizeUrlEncodedPart, parseUrlEncodedParts, serializeUrlEncodedParts } from './urlencoded.js';
|
|
9
|
+
export { hasUnsafeHeaderFieldChars, validateHeaderField, validateHeaders } from './httpHeaders.js';
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight opt-in very-verbose logging for outbound HTTP request details.
|
|
3
|
+
*
|
|
4
|
+
* Very-verbose mode is enabled with `-vv` / `--very-verbose` or `HARBOR_VERBOSE=2`.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Whether very-verbose logging is active for the lifetime of this process.
|
|
8
|
+
*/
|
|
9
|
+
export declare const isVeryVerbose: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Logs outbound HTTP request details only when very-verbose (`-vv`) is enabled.
|
|
12
|
+
*
|
|
13
|
+
* Use for method, URL, request headers, and request body. Response headers and
|
|
14
|
+
* response bodies are never logged through this helper.
|
|
15
|
+
*
|
|
16
|
+
* @param args - Values forwarded to `console.log`.
|
|
17
|
+
*/
|
|
18
|
+
export declare function logRequest(...args: unknown[]): void;
|
|
19
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAiBH;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,OAA6B,CAAC;AAE1D;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAInD"}
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight opt-in very-verbose logging for outbound HTTP request details.
|
|
3
|
+
*
|
|
4
|
+
* Very-verbose mode is enabled with `-vv` / `--very-verbose` or `HARBOR_VERBOSE=2`.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Determines whether very-verbose logging should be enabled for this process.
|
|
8
|
+
*
|
|
9
|
+
* Reads `process.argv` for `-vv`/`--very-verbose` and `HARBOR_VERBOSE=2`.
|
|
10
|
+
*
|
|
11
|
+
* @returns True when very-verbose logging is requested.
|
|
12
|
+
*/
|
|
13
|
+
function detectVeryVerbose() {
|
|
14
|
+
return (process.argv.includes('-vv') ||
|
|
15
|
+
process.argv.includes('--very-verbose') ||
|
|
16
|
+
process.env['HARBOR_VERBOSE'] === '2');
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Whether very-verbose logging is active for the lifetime of this process.
|
|
20
|
+
*/
|
|
21
|
+
export const isVeryVerbose = detectVeryVerbose();
|
|
22
|
+
/**
|
|
23
|
+
* Logs outbound HTTP request details only when very-verbose (`-vv`) is enabled.
|
|
24
|
+
*
|
|
25
|
+
* Use for method, URL, request headers, and request body. Response headers and
|
|
26
|
+
* response bodies are never logged through this helper.
|
|
27
|
+
*
|
|
28
|
+
* @param args - Values forwarded to `console.log`.
|
|
29
|
+
*/
|
|
30
|
+
export function logRequest(...args) {
|
|
31
|
+
if (isVeryVerbose) {
|
|
32
|
+
console.log('[request]', ...args);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ProxySettings } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Absolute ceiling for the configurable max response size setting (MB).
|
|
4
|
+
*/
|
|
5
|
+
export declare const HARD_MAX_RESPONSE_SIZE_MB = 512;
|
|
6
|
+
/**
|
|
7
|
+
* Default proxy settings used when request settings are not supplied.
|
|
8
|
+
*/
|
|
9
|
+
export declare const DEFAULT_PROXY_SETTINGS: ProxySettings;
|
|
10
|
+
/**
|
|
11
|
+
* HTTP execution settings consumed by {@link Requester}.
|
|
12
|
+
*
|
|
13
|
+
* A subset of the main app's GeneralSettings — excludes editor, theme, and
|
|
14
|
+
* global variable fields so the package stays self-contained.
|
|
15
|
+
*/
|
|
16
|
+
export interface RequestSettings {
|
|
17
|
+
/**
|
|
18
|
+
* Request timeout in milliseconds; 0 disables the timeout.
|
|
19
|
+
*/
|
|
20
|
+
requestTimeoutMs: number;
|
|
21
|
+
/**
|
|
22
|
+
* Maximum response body size in megabytes; 0 disables the configurable limit.
|
|
23
|
+
*/
|
|
24
|
+
maxResponseSizeMb: number;
|
|
25
|
+
/**
|
|
26
|
+
* When true, TLS certificates are verified for HTTPS requests.
|
|
27
|
+
*/
|
|
28
|
+
verifySsl: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* When true, 3xx responses are followed automatically.
|
|
31
|
+
*/
|
|
32
|
+
followRedirects: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* Global HTTP proxy applied to every outbound request.
|
|
35
|
+
*/
|
|
36
|
+
proxy: ProxySettings;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Default request settings matching the main app's general settings defaults.
|
|
40
|
+
*/
|
|
41
|
+
export declare const DEFAULT_REQUEST_SETTINGS: RequestSettings;
|
|
42
|
+
//# sourceMappingURL=settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../src/settings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;GAEG;AACH,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAE7C;;GAEG;AACH,eAAO,MAAM,sBAAsB,EAAE,aAQpC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,gBAAgB,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,eAAe,EAAE,OAAO,CAAC;IAEzB;;OAEG;IACH,KAAK,EAAE,aAAa,CAAC;CACtB;AAED;;GAEG;AACH,eAAO,MAAM,wBAAwB,EAAE,eAMtC,CAAC"}
|
package/dist/settings.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Absolute ceiling for the configurable max response size setting (MB).
|
|
3
|
+
*/
|
|
4
|
+
export const HARD_MAX_RESPONSE_SIZE_MB = 512;
|
|
5
|
+
/**
|
|
6
|
+
* Default proxy settings used when request settings are not supplied.
|
|
7
|
+
*/
|
|
8
|
+
export const DEFAULT_PROXY_SETTINGS = {
|
|
9
|
+
enabled: false,
|
|
10
|
+
protocol: 'http',
|
|
11
|
+
host: '',
|
|
12
|
+
port: 8080,
|
|
13
|
+
authEnabled: false,
|
|
14
|
+
username: '',
|
|
15
|
+
password: ''
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Default request settings matching the main app's general settings defaults.
|
|
19
|
+
*/
|
|
20
|
+
export const DEFAULT_REQUEST_SETTINGS = {
|
|
21
|
+
requestTimeoutMs: 30000,
|
|
22
|
+
maxResponseSizeMb: 50,
|
|
23
|
+
verifySsl: true,
|
|
24
|
+
followRedirects: true,
|
|
25
|
+
proxy: { ...DEFAULT_PROXY_SETTINGS }
|
|
26
|
+
};
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supported HTTP request methods.
|
|
3
|
+
*/
|
|
4
|
+
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
|
|
5
|
+
/**
|
|
6
|
+
* Request body content type.
|
|
7
|
+
*/
|
|
8
|
+
export type BodyType = 'none' | 'json' | 'text' | 'multipart' | 'urlencoded';
|
|
9
|
+
/**
|
|
10
|
+
* Field type for a multipart/form-data part.
|
|
11
|
+
*/
|
|
12
|
+
export type FormDataPartType = 'text' | 'file';
|
|
13
|
+
/**
|
|
14
|
+
* A single part in a multipart/form-data body.
|
|
15
|
+
*/
|
|
16
|
+
export interface FormDataPart {
|
|
17
|
+
/**
|
|
18
|
+
* Form field name.
|
|
19
|
+
*/
|
|
20
|
+
key: string;
|
|
21
|
+
/**
|
|
22
|
+
* Text value when type is text; ignored for file parts.
|
|
23
|
+
*/
|
|
24
|
+
value: string;
|
|
25
|
+
/**
|
|
26
|
+
* When false, the part is excluded when building the request.
|
|
27
|
+
*/
|
|
28
|
+
enabled: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Whether this part is a text field or file upload.
|
|
31
|
+
*/
|
|
32
|
+
type: FormDataPartType;
|
|
33
|
+
/**
|
|
34
|
+
* Absolute file paths for file parts; supports one or more files per field.
|
|
35
|
+
*/
|
|
36
|
+
files: string[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* A key-value pair with an enable toggle for headers and query params.
|
|
40
|
+
*/
|
|
41
|
+
export interface KeyValue {
|
|
42
|
+
/**
|
|
43
|
+
* Header or query parameter name.
|
|
44
|
+
*/
|
|
45
|
+
key: string;
|
|
46
|
+
/**
|
|
47
|
+
* Header or query parameter value.
|
|
48
|
+
*/
|
|
49
|
+
value: string;
|
|
50
|
+
/**
|
|
51
|
+
* When false, the pair is ignored when building the request.
|
|
52
|
+
*/
|
|
53
|
+
enabled: boolean;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Proxy protocol used to connect to the proxy server.
|
|
57
|
+
*/
|
|
58
|
+
export type ProxyProtocol = 'http' | 'https';
|
|
59
|
+
/**
|
|
60
|
+
* Global HTTP proxy configuration applied to every outbound request.
|
|
61
|
+
*/
|
|
62
|
+
export interface ProxySettings {
|
|
63
|
+
/**
|
|
64
|
+
* When true, outbound requests are routed through the configured proxy.
|
|
65
|
+
*/
|
|
66
|
+
enabled: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Protocol used to connect to the proxy server.
|
|
69
|
+
*/
|
|
70
|
+
protocol: ProxyProtocol;
|
|
71
|
+
/**
|
|
72
|
+
* Proxy server hostname or IP address.
|
|
73
|
+
*/
|
|
74
|
+
host: string;
|
|
75
|
+
/**
|
|
76
|
+
* Proxy server port.
|
|
77
|
+
*/
|
|
78
|
+
port: number;
|
|
79
|
+
/**
|
|
80
|
+
* When true, HTTP Basic authentication credentials are sent to the proxy.
|
|
81
|
+
*/
|
|
82
|
+
authEnabled: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* Username for proxy HTTP Basic authentication.
|
|
85
|
+
*/
|
|
86
|
+
username: string;
|
|
87
|
+
/**
|
|
88
|
+
* Password for proxy HTTP Basic authentication.
|
|
89
|
+
*/
|
|
90
|
+
password: string;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Input for sending an HTTP request from the renderer.
|
|
94
|
+
*/
|
|
95
|
+
export interface SendRequestInput {
|
|
96
|
+
/**
|
|
97
|
+
* HTTP method to use for the request.
|
|
98
|
+
*/
|
|
99
|
+
method: HttpMethod;
|
|
100
|
+
/**
|
|
101
|
+
* Request URL without query parameters.
|
|
102
|
+
*/
|
|
103
|
+
url: string;
|
|
104
|
+
/**
|
|
105
|
+
* Request headers as editable key-value pairs.
|
|
106
|
+
*/
|
|
107
|
+
headers: KeyValue[];
|
|
108
|
+
/**
|
|
109
|
+
* Query parameters as editable key-value pairs.
|
|
110
|
+
*/
|
|
111
|
+
params: KeyValue[];
|
|
112
|
+
/**
|
|
113
|
+
* Raw request body content.
|
|
114
|
+
*/
|
|
115
|
+
body: string;
|
|
116
|
+
/**
|
|
117
|
+
* Content type of the request body.
|
|
118
|
+
*/
|
|
119
|
+
bodyType: BodyType;
|
|
120
|
+
/**
|
|
121
|
+
* Saved collection request id when the send originated from a saved request tab.
|
|
122
|
+
*/
|
|
123
|
+
sourceRequestId?: number;
|
|
124
|
+
/**
|
|
125
|
+
* Display name from the request tab when {@link sourceRequestId} is set.
|
|
126
|
+
*/
|
|
127
|
+
sourceRequestName?: string;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Metadata for the HTTP request as sent. Multipart {@link body} is a display
|
|
131
|
+
* summary of form fields, not the raw wire payload.
|
|
132
|
+
*/
|
|
133
|
+
export interface SentRequest {
|
|
134
|
+
/**
|
|
135
|
+
* HTTP method used for the request.
|
|
136
|
+
*/
|
|
137
|
+
method: HttpMethod;
|
|
138
|
+
/**
|
|
139
|
+
* Fully resolved request URL including query parameters.
|
|
140
|
+
*/
|
|
141
|
+
url: string;
|
|
142
|
+
/**
|
|
143
|
+
* Request headers as a flat key-value map.
|
|
144
|
+
*/
|
|
145
|
+
headers: Record<string, string>;
|
|
146
|
+
/**
|
|
147
|
+
* Body content for display. For multipart, a human-readable summary of form
|
|
148
|
+
* fields and file names — not the raw multipart bytes. For other body types,
|
|
149
|
+
* the literal string sent on the wire, or empty when none.
|
|
150
|
+
*/
|
|
151
|
+
body: string;
|
|
152
|
+
/**
|
|
153
|
+
* Content type of the request body; used to interpret {@link body}.
|
|
154
|
+
*/
|
|
155
|
+
bodyType?: BodyType;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* One hop in a redirect chain recorded while following 3xx responses.
|
|
159
|
+
*/
|
|
160
|
+
export interface RedirectHop {
|
|
161
|
+
/**
|
|
162
|
+
* Status code of the redirect response (301, 302, 303, 307, or 308).
|
|
163
|
+
*/
|
|
164
|
+
status: number;
|
|
165
|
+
/**
|
|
166
|
+
* Status text of the redirect response.
|
|
167
|
+
*/
|
|
168
|
+
statusText: string;
|
|
169
|
+
/**
|
|
170
|
+
* Absolute URL that was requested for this hop.
|
|
171
|
+
*/
|
|
172
|
+
url: string;
|
|
173
|
+
/**
|
|
174
|
+
* Resolved absolute URL from the Location header.
|
|
175
|
+
*/
|
|
176
|
+
location: string;
|
|
177
|
+
/**
|
|
178
|
+
* HTTP method used for this hop.
|
|
179
|
+
*/
|
|
180
|
+
method: HttpMethod;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Result of an HTTP request including timing and size metadata.
|
|
184
|
+
*/
|
|
185
|
+
export interface SendResult {
|
|
186
|
+
/**
|
|
187
|
+
* HTTP status code, or 0 when the request failed before a response.
|
|
188
|
+
*/
|
|
189
|
+
status: number;
|
|
190
|
+
/**
|
|
191
|
+
* HTTP status text from the response.
|
|
192
|
+
*/
|
|
193
|
+
statusText: string;
|
|
194
|
+
/**
|
|
195
|
+
* Response headers as a flat key-value map.
|
|
196
|
+
*/
|
|
197
|
+
headers: Record<string, string>;
|
|
198
|
+
/**
|
|
199
|
+
* Response body as text.
|
|
200
|
+
*/
|
|
201
|
+
body: string;
|
|
202
|
+
/**
|
|
203
|
+
* Base64-encoded response body for image responses only; omitted for other content types.
|
|
204
|
+
*/
|
|
205
|
+
bodyBase64?: string;
|
|
206
|
+
/**
|
|
207
|
+
* Round-trip time in milliseconds.
|
|
208
|
+
*/
|
|
209
|
+
timeMs: number;
|
|
210
|
+
/**
|
|
211
|
+
* Response body size in bytes.
|
|
212
|
+
*/
|
|
213
|
+
sizeBytes: number;
|
|
214
|
+
/**
|
|
215
|
+
* Error message when the request failed; omitted on success.
|
|
216
|
+
*/
|
|
217
|
+
error?: string;
|
|
218
|
+
/**
|
|
219
|
+
* Set-Cookie header values from the response; used by the cookie jar.
|
|
220
|
+
*/
|
|
221
|
+
setCookieHeaders?: string[];
|
|
222
|
+
/**
|
|
223
|
+
* The outgoing request as actually sent; omitted on older results.
|
|
224
|
+
*/
|
|
225
|
+
request?: SentRequest;
|
|
226
|
+
/**
|
|
227
|
+
* Ordered redirect hops that were followed; omitted when none.
|
|
228
|
+
*/
|
|
229
|
+
redirects?: RedirectHop[];
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { KeyValue } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Returns a blank urlencoded row with enabled set to true.
|
|
4
|
+
*/
|
|
5
|
+
export declare function emptyUrlEncodedPart(): KeyValue;
|
|
6
|
+
/**
|
|
7
|
+
* Coerces a partial or legacy key-value record to the full KeyValue shape.
|
|
8
|
+
*
|
|
9
|
+
* @param row - Raw row fields from storage or import.
|
|
10
|
+
* @returns Normalized key-value row with defaults for missing fields.
|
|
11
|
+
*/
|
|
12
|
+
export declare function normalizeUrlEncodedPart(row: Partial<KeyValue>): KeyValue;
|
|
13
|
+
/**
|
|
14
|
+
* Parses a serialized urlencoded body string into key-value rows.
|
|
15
|
+
*
|
|
16
|
+
* @param body - JSON array stored in the request body field.
|
|
17
|
+
* @returns Parsed rows, or an empty array when body is empty or invalid.
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseUrlEncodedParts(body: string): KeyValue[];
|
|
20
|
+
/**
|
|
21
|
+
* Serializes urlencoded rows for storage in the request body field.
|
|
22
|
+
*
|
|
23
|
+
* @param rows - Key-value rows to serialize.
|
|
24
|
+
* @returns JSON string, or an empty string when there are no rows.
|
|
25
|
+
*/
|
|
26
|
+
export declare function serializeUrlEncodedParts(rows: KeyValue[]): string;
|
|
27
|
+
//# sourceMappingURL=urlencoded.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"urlencoded.d.ts","sourceRoot":"","sources":["../src/urlencoded.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,QAAQ,CAE9C;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAMxE;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,EAAE,CAe7D;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,CAKjE"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns a blank urlencoded row with enabled set to true.
|
|
3
|
+
*/
|
|
4
|
+
export function emptyUrlEncodedPart() {
|
|
5
|
+
return { key: '', value: '', enabled: true };
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Coerces a partial or legacy key-value record to the full KeyValue shape.
|
|
9
|
+
*
|
|
10
|
+
* @param row - Raw row fields from storage or import.
|
|
11
|
+
* @returns Normalized key-value row with defaults for missing fields.
|
|
12
|
+
*/
|
|
13
|
+
export function normalizeUrlEncodedPart(row) {
|
|
14
|
+
return {
|
|
15
|
+
key: typeof row.key === 'string' ? row.key : '',
|
|
16
|
+
value: typeof row.value === 'string' ? row.value : '',
|
|
17
|
+
enabled: row.enabled !== false
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Parses a serialized urlencoded body string into key-value rows.
|
|
22
|
+
*
|
|
23
|
+
* @param body - JSON array stored in the request body field.
|
|
24
|
+
* @returns Parsed rows, or an empty array when body is empty or invalid.
|
|
25
|
+
*/
|
|
26
|
+
export function parseUrlEncodedParts(body) {
|
|
27
|
+
const trimmed = body.trim();
|
|
28
|
+
if (!trimmed) {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const parsed = JSON.parse(trimmed);
|
|
33
|
+
if (!Array.isArray(parsed)) {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
return parsed.map((row) => normalizeUrlEncodedPart(row));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Serializes urlencoded rows for storage in the request body field.
|
|
44
|
+
*
|
|
45
|
+
* @param rows - Key-value rows to serialize.
|
|
46
|
+
* @returns JSON string, or an empty string when there are no rows.
|
|
47
|
+
*/
|
|
48
|
+
export function serializeUrlEncodedParts(rows) {
|
|
49
|
+
if (rows.length === 0) {
|
|
50
|
+
return '';
|
|
51
|
+
}
|
|
52
|
+
return JSON.stringify(rows.map((row) => normalizeUrlEncodedPart(row)));
|
|
53
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@harborclient/http",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "HTTP utilities for HarborClient.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"harborclient",
|
|
7
|
+
"http",
|
|
8
|
+
"typescript"
|
|
9
|
+
],
|
|
10
|
+
"homepage": "https://github.com/harborclient/http",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/harborclient/http/issues"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/harborclient/http.git"
|
|
17
|
+
},
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"author": {
|
|
20
|
+
"name": "HarborClient",
|
|
21
|
+
"email": "contact@harborclient.com"
|
|
22
|
+
},
|
|
23
|
+
"type": "module",
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"types": "./dist/index.d.ts",
|
|
26
|
+
"exports": {
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"import": "./dist/index.js",
|
|
30
|
+
"default": "./dist/index.js"
|
|
31
|
+
},
|
|
32
|
+
"./formData": {
|
|
33
|
+
"types": "./dist/formData.d.ts",
|
|
34
|
+
"import": "./dist/formData.js",
|
|
35
|
+
"default": "./dist/formData.js"
|
|
36
|
+
},
|
|
37
|
+
"./urlencoded": {
|
|
38
|
+
"types": "./dist/urlencoded.d.ts",
|
|
39
|
+
"import": "./dist/urlencoded.js",
|
|
40
|
+
"default": "./dist/urlencoded.js"
|
|
41
|
+
},
|
|
42
|
+
"./httpHeaders": {
|
|
43
|
+
"types": "./dist/httpHeaders.d.ts",
|
|
44
|
+
"import": "./dist/httpHeaders.js",
|
|
45
|
+
"default": "./dist/httpHeaders.js"
|
|
46
|
+
},
|
|
47
|
+
"./types": {
|
|
48
|
+
"types": "./dist/types.d.ts",
|
|
49
|
+
"import": "./dist/types.js",
|
|
50
|
+
"default": "./dist/types.js"
|
|
51
|
+
},
|
|
52
|
+
"./settings": {
|
|
53
|
+
"types": "./dist/settings.d.ts",
|
|
54
|
+
"import": "./dist/settings.js",
|
|
55
|
+
"default": "./dist/settings.js"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"files": [
|
|
59
|
+
"dist"
|
|
60
|
+
],
|
|
61
|
+
"engines": {
|
|
62
|
+
"node": ">=24"
|
|
63
|
+
},
|
|
64
|
+
"publishConfig": {
|
|
65
|
+
"access": "public",
|
|
66
|
+
"provenance": true
|
|
67
|
+
},
|
|
68
|
+
"dependencies": {
|
|
69
|
+
"undici": "^6.27.0"
|
|
70
|
+
},
|
|
71
|
+
"devDependencies": {
|
|
72
|
+
"concurrently": "^8.2.2",
|
|
73
|
+
"vitepress": "^1.6.4",
|
|
74
|
+
"@eslint/js": "^9.39.4",
|
|
75
|
+
"@types/node": "^26.0.1",
|
|
76
|
+
"eslint": "^9.39.4",
|
|
77
|
+
"eslint-config-prettier": "^10.1.5",
|
|
78
|
+
"prettier": "^3.8.4",
|
|
79
|
+
"typescript": "^5.8.3",
|
|
80
|
+
"typescript-eslint": "^8.36.0",
|
|
81
|
+
"vitest": "^4.1.9"
|
|
82
|
+
},
|
|
83
|
+
"scripts": {
|
|
84
|
+
"build": "tsc -p tsconfig.build.json",
|
|
85
|
+
"clean": "rm -rf dist",
|
|
86
|
+
"docs:build": "pnpm docs:build:nav && vitepress build docs",
|
|
87
|
+
"docs:build:nav": "node scripts/build-docs-nav.mjs && node scripts/assert-docs-slugs.mjs",
|
|
88
|
+
"docs:preview": "pnpm docs:build && vitepress preview docs",
|
|
89
|
+
"docs:serve": "pnpm docs:build:nav && concurrently --kill-others --prefixColors=auto -n nav,vp \"node scripts/watch-docs-nav.mjs\" \"vitepress dev docs\"",
|
|
90
|
+
"format": "prettier --write .",
|
|
91
|
+
"format:check": "prettier --check .",
|
|
92
|
+
"lint": "eslint --cache .",
|
|
93
|
+
"release": "gh workflow run Release --ref main -f release_type=patch",
|
|
94
|
+
"release:patch": "gh workflow run Release --ref main -f release_type=patch",
|
|
95
|
+
"release:minor": "gh workflow run Release --ref main -f release_type=minor",
|
|
96
|
+
"release:major": "gh workflow run Release --ref main -f release_type=major",
|
|
97
|
+
"typecheck": "tsc --noEmit",
|
|
98
|
+
"test": "vitest run",
|
|
99
|
+
"test:watch": "vitest"
|
|
100
|
+
}
|
|
101
|
+
}
|