nlcurl 0.1.0
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 +162 -0
- package/dist/cli/args.d.ts +42 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +262 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +114 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/output.d.ts +22 -0
- package/dist/cli/output.d.ts.map +1 -0
- package/dist/cli/output.js +105 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cookies/jar.d.ts +41 -0
- package/dist/cookies/jar.d.ts.map +1 -0
- package/dist/cookies/jar.js +148 -0
- package/dist/cookies/jar.js.map +1 -0
- package/dist/cookies/parser.d.ts +24 -0
- package/dist/cookies/parser.d.ts.map +1 -0
- package/dist/cookies/parser.js +93 -0
- package/dist/cookies/parser.js.map +1 -0
- package/dist/core/client.d.ts +79 -0
- package/dist/core/client.d.ts.map +1 -0
- package/dist/core/client.js +106 -0
- package/dist/core/client.js.map +1 -0
- package/dist/core/errors.d.ts +36 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +65 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/request.d.ts +96 -0
- package/dist/core/request.d.ts.map +1 -0
- package/dist/core/request.js +5 -0
- package/dist/core/request.js.map +1 -0
- package/dist/core/response.d.ts +48 -0
- package/dist/core/response.d.ts.map +1 -0
- package/dist/core/response.js +65 -0
- package/dist/core/response.js.map +1 -0
- package/dist/core/session.d.ts +60 -0
- package/dist/core/session.d.ts.map +1 -0
- package/dist/core/session.js +305 -0
- package/dist/core/session.js.map +1 -0
- package/dist/fingerprints/akamai.d.ts +17 -0
- package/dist/fingerprints/akamai.d.ts.map +1 -0
- package/dist/fingerprints/akamai.js +30 -0
- package/dist/fingerprints/akamai.js.map +1 -0
- package/dist/fingerprints/database.d.ts +33 -0
- package/dist/fingerprints/database.d.ts.map +1 -0
- package/dist/fingerprints/database.js +68 -0
- package/dist/fingerprints/database.js.map +1 -0
- package/dist/fingerprints/extensions.d.ts +49 -0
- package/dist/fingerprints/extensions.d.ts.map +1 -0
- package/dist/fingerprints/extensions.js +178 -0
- package/dist/fingerprints/extensions.js.map +1 -0
- package/dist/fingerprints/ja3.d.ts +32 -0
- package/dist/fingerprints/ja3.d.ts.map +1 -0
- package/dist/fingerprints/ja3.js +64 -0
- package/dist/fingerprints/ja3.js.map +1 -0
- package/dist/fingerprints/profiles/chrome.d.ts +30 -0
- package/dist/fingerprints/profiles/chrome.d.ts.map +1 -0
- package/dist/fingerprints/profiles/chrome.js +202 -0
- package/dist/fingerprints/profiles/chrome.js.map +1 -0
- package/dist/fingerprints/profiles/edge.d.ts +16 -0
- package/dist/fingerprints/profiles/edge.d.ts.map +1 -0
- package/dist/fingerprints/profiles/edge.js +61 -0
- package/dist/fingerprints/profiles/edge.js.map +1 -0
- package/dist/fingerprints/profiles/firefox.d.ts +13 -0
- package/dist/fingerprints/profiles/firefox.d.ts.map +1 -0
- package/dist/fingerprints/profiles/firefox.js +160 -0
- package/dist/fingerprints/profiles/firefox.js.map +1 -0
- package/dist/fingerprints/profiles/safari.d.ts +16 -0
- package/dist/fingerprints/profiles/safari.d.ts.map +1 -0
- package/dist/fingerprints/profiles/safari.js +140 -0
- package/dist/fingerprints/profiles/safari.js.map +1 -0
- package/dist/fingerprints/profiles/tor.d.ts +14 -0
- package/dist/fingerprints/profiles/tor.d.ts.map +1 -0
- package/dist/fingerprints/profiles/tor.js +136 -0
- package/dist/fingerprints/profiles/tor.js.map +1 -0
- package/dist/fingerprints/types.d.ts +104 -0
- package/dist/fingerprints/types.d.ts.map +1 -0
- package/dist/fingerprints/types.js +9 -0
- package/dist/fingerprints/types.js.map +1 -0
- package/dist/http/h1/client.d.ts +21 -0
- package/dist/http/h1/client.d.ts.map +1 -0
- package/dist/http/h1/client.js +136 -0
- package/dist/http/h1/client.js.map +1 -0
- package/dist/http/h1/encoder.d.ts +11 -0
- package/dist/http/h1/encoder.d.ts.map +1 -0
- package/dist/http/h1/encoder.js +75 -0
- package/dist/http/h1/encoder.js.map +1 -0
- package/dist/http/h1/parser.d.ts +61 -0
- package/dist/http/h1/parser.d.ts.map +1 -0
- package/dist/http/h1/parser.js +258 -0
- package/dist/http/h1/parser.js.map +1 -0
- package/dist/http/h2/client.d.ts +48 -0
- package/dist/http/h2/client.d.ts.map +1 -0
- package/dist/http/h2/client.js +376 -0
- package/dist/http/h2/client.js.map +1 -0
- package/dist/http/h2/frames.d.ts +65 -0
- package/dist/http/h2/frames.d.ts.map +1 -0
- package/dist/http/h2/frames.js +184 -0
- package/dist/http/h2/frames.js.map +1 -0
- package/dist/http/h2/hpack.d.ts +27 -0
- package/dist/http/h2/hpack.d.ts.map +1 -0
- package/dist/http/h2/hpack.js +423 -0
- package/dist/http/h2/hpack.js.map +1 -0
- package/dist/http/negotiator.d.ts +36 -0
- package/dist/http/negotiator.d.ts.map +1 -0
- package/dist/http/negotiator.js +101 -0
- package/dist/http/negotiator.js.map +1 -0
- package/dist/http/pool.d.ts +63 -0
- package/dist/http/pool.d.ts.map +1 -0
- package/dist/http/pool.js +177 -0
- package/dist/http/pool.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/interceptor.d.ts +27 -0
- package/dist/middleware/interceptor.d.ts.map +1 -0
- package/dist/middleware/interceptor.js +35 -0
- package/dist/middleware/interceptor.js.map +1 -0
- package/dist/middleware/rate-limiter.d.ts +26 -0
- package/dist/middleware/rate-limiter.d.ts.map +1 -0
- package/dist/middleware/rate-limiter.js +59 -0
- package/dist/middleware/rate-limiter.js.map +1 -0
- package/dist/middleware/retry.d.ts +17 -0
- package/dist/middleware/retry.d.ts.map +1 -0
- package/dist/middleware/retry.js +64 -0
- package/dist/middleware/retry.js.map +1 -0
- package/dist/proxy/http-proxy.d.ts +23 -0
- package/dist/proxy/http-proxy.d.ts.map +1 -0
- package/dist/proxy/http-proxy.js +93 -0
- package/dist/proxy/http-proxy.js.map +1 -0
- package/dist/proxy/socks.d.ts +24 -0
- package/dist/proxy/socks.d.ts.map +1 -0
- package/dist/proxy/socks.js +196 -0
- package/dist/proxy/socks.js.map +1 -0
- package/dist/tls/constants.d.ts +142 -0
- package/dist/tls/constants.d.ts.map +1 -0
- package/dist/tls/constants.js +163 -0
- package/dist/tls/constants.js.map +1 -0
- package/dist/tls/node-engine.d.ts +22 -0
- package/dist/tls/node-engine.d.ts.map +1 -0
- package/dist/tls/node-engine.js +190 -0
- package/dist/tls/node-engine.js.map +1 -0
- package/dist/tls/stealth/client-hello.d.ts +38 -0
- package/dist/tls/stealth/client-hello.d.ts.map +1 -0
- package/dist/tls/stealth/client-hello.js +197 -0
- package/dist/tls/stealth/client-hello.js.map +1 -0
- package/dist/tls/stealth/engine.d.ts +16 -0
- package/dist/tls/stealth/engine.d.ts.map +1 -0
- package/dist/tls/stealth/engine.js +196 -0
- package/dist/tls/stealth/engine.js.map +1 -0
- package/dist/tls/stealth/handshake.d.ts +45 -0
- package/dist/tls/stealth/handshake.d.ts.map +1 -0
- package/dist/tls/stealth/handshake.js +403 -0
- package/dist/tls/stealth/handshake.js.map +1 -0
- package/dist/tls/stealth/key-schedule.d.ts +85 -0
- package/dist/tls/stealth/key-schedule.d.ts.map +1 -0
- package/dist/tls/stealth/key-schedule.js +141 -0
- package/dist/tls/stealth/key-schedule.js.map +1 -0
- package/dist/tls/stealth/record-layer.d.ts +74 -0
- package/dist/tls/stealth/record-layer.d.ts.map +1 -0
- package/dist/tls/stealth/record-layer.js +167 -0
- package/dist/tls/stealth/record-layer.js.map +1 -0
- package/dist/tls/types.d.ts +58 -0
- package/dist/tls/types.d.ts.map +1 -0
- package/dist/tls/types.js +6 -0
- package/dist/tls/types.js.map +1 -0
- package/dist/utils/buffer-reader.d.ts +32 -0
- package/dist/utils/buffer-reader.d.ts.map +1 -0
- package/dist/utils/buffer-reader.js +99 -0
- package/dist/utils/buffer-reader.js.map +1 -0
- package/dist/utils/buffer-writer.d.ts +35 -0
- package/dist/utils/buffer-writer.d.ts.map +1 -0
- package/dist/utils/buffer-writer.js +121 -0
- package/dist/utils/buffer-writer.js.map +1 -0
- package/dist/utils/encoding.d.ts +19 -0
- package/dist/utils/encoding.d.ts.map +1 -0
- package/dist/utils/encoding.js +63 -0
- package/dist/utils/encoding.js.map +1 -0
- package/dist/utils/logger.d.ts +24 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +56 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/url.d.ts +22 -0
- package/dist/utils/url.d.ts.map +1 -0
- package/dist/utils/url.js +56 -0
- package/dist/utils/url.js.map +1 -0
- package/dist/ws/client.d.ts +63 -0
- package/dist/ws/client.d.ts.map +1 -0
- package/dist/ws/client.js +273 -0
- package/dist/ws/client.js.map +1 -0
- package/dist/ws/frame.d.ts +44 -0
- package/dist/ws/frame.d.ts.map +1 -0
- package/dist/ws/frame.js +146 -0
- package/dist/ws/frame.js.map +1 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 devAlphaSystem
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# NLcURL
|
|
2
|
+
|
|
3
|
+
Pure TypeScript HTTP client with browser fingerprint impersonation.
|
|
4
|
+
|
|
5
|
+
NLcURL provides session-based and one-shot HTTP APIs, browser profile impersonation, HTTP/2 support, cookie management, and a CLI. The project has zero runtime dependencies and uses only Node.js built-in modules.
|
|
6
|
+
|
|
7
|
+
## Highlights
|
|
8
|
+
|
|
9
|
+
- Zero runtime dependencies
|
|
10
|
+
- Session API with connection pooling
|
|
11
|
+
- HTTP/1.1 and HTTP/2 (ALPN negotiated)
|
|
12
|
+
- Browser profile impersonation (Chrome, Firefox, Safari, Edge, Tor)
|
|
13
|
+
- Optional custom JA3 and Akamai H2 fingerprint values in request model
|
|
14
|
+
- Cookie jar with RFC 6265-like behavior
|
|
15
|
+
- CLI (`nlcurl`) for scripted and interactive use
|
|
16
|
+
- WebSocket client with optional impersonated TLS handshake
|
|
17
|
+
|
|
18
|
+
## Requirements
|
|
19
|
+
|
|
20
|
+
- Node.js `>= 18.17.0`
|
|
21
|
+
- npm (or compatible package manager)
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install nlcurl
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
For local development:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm install
|
|
33
|
+
npm run build
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Quick Start
|
|
37
|
+
|
|
38
|
+
### One-shot request
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import { request } from "nlcurl";
|
|
42
|
+
|
|
43
|
+
const response = await request({
|
|
44
|
+
url: "https://httpbin.org/get",
|
|
45
|
+
impersonate: "chrome136",
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
console.log(response.status);
|
|
49
|
+
console.log(response.json());
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Session-based usage
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { createSession } from "nlcurl";
|
|
56
|
+
|
|
57
|
+
const session = createSession({
|
|
58
|
+
baseURL: "https://httpbin.org",
|
|
59
|
+
impersonate: "firefox138",
|
|
60
|
+
followRedirects: true,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const res = await session.get("/headers");
|
|
64
|
+
console.log(res.json());
|
|
65
|
+
|
|
66
|
+
session.close();
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### CLI usage
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
nlcurl --impersonate chrome136 https://tls.browserleaks.com/json
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## CLI Reference
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
nlcurl [OPTIONS] <URL>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Key options:
|
|
82
|
+
|
|
83
|
+
- `-X, --request <METHOD>` HTTP method
|
|
84
|
+
- `-H, --header <Name: Value>` add request header
|
|
85
|
+
- `-d, --data <DATA>` request body
|
|
86
|
+
- `--data-raw <DATA>` raw request body
|
|
87
|
+
- `-A, --user-agent <AGENT>` custom User-Agent
|
|
88
|
+
- `-o, --output <FILE>` write response body to file
|
|
89
|
+
- `-I, --head` send HEAD request
|
|
90
|
+
- `-i, --include` include response headers
|
|
91
|
+
- `-v, --verbose` verbose request/response output
|
|
92
|
+
- `-s, --silent` suppress error output
|
|
93
|
+
- `--compressed` request compressed response
|
|
94
|
+
- `--impersonate <PROFILE>` browser profile
|
|
95
|
+
- `--stealth` use stealth TLS engine
|
|
96
|
+
- `--ja3 <FINGERPRINT>` custom JA3 fingerprint string
|
|
97
|
+
- `--akamai <FINGERPRINT>` custom Akamai HTTP/2 fingerprint string
|
|
98
|
+
- `--list-profiles` list available profiles
|
|
99
|
+
- `-x, --proxy <URL>` proxy URL (request model supports it)
|
|
100
|
+
- `-U, --proxy-user <USER:PASS>` proxy auth pair
|
|
101
|
+
- `-k, --insecure` disable TLS verification
|
|
102
|
+
- `-L, --location` follow redirects (default behavior)
|
|
103
|
+
- `--no-location` disable redirect following
|
|
104
|
+
- `--max-redirs <NUM>` max redirects (default `20`)
|
|
105
|
+
- `-m, --max-time <SECONDS>` total timeout
|
|
106
|
+
- `--http1.1` force HTTP/1.1
|
|
107
|
+
- `--http2` force HTTP/2
|
|
108
|
+
- `-b, --cookie <DATA>` send cookie header
|
|
109
|
+
- `-c, --cookie-jar <FILE>` capture cookie jar target file
|
|
110
|
+
- `-h, --help` show help
|
|
111
|
+
- `-V, --version` show version
|
|
112
|
+
|
|
113
|
+
For examples, see `docs/SETUP.md` and `docs/API.md`.
|
|
114
|
+
|
|
115
|
+
## Supported Browser Families
|
|
116
|
+
|
|
117
|
+
- Chrome (`chrome99` through `chrome136`, plus `chrome_latest` and `chrome` alias)
|
|
118
|
+
- Firefox (`firefox133` through `firefox138`, plus `firefox_latest` and `firefox` alias)
|
|
119
|
+
- Safari (`safari153` through `safari182`, plus `safari_latest` and `safari` alias)
|
|
120
|
+
- Edge (`edge99`, `edge101`, `edge126`, `edge131`, `edge136`, `edge_latest`, `edge` alias)
|
|
121
|
+
- Tor (`tor133`, `tor140`, `tor145`, `tor_latest`, `tor` alias)
|
|
122
|
+
|
|
123
|
+
Run `nlcurl --list-profiles` to view the exact runtime list.
|
|
124
|
+
|
|
125
|
+
## Development
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
npm install
|
|
129
|
+
npm run lint
|
|
130
|
+
npm run test
|
|
131
|
+
npm run test:integration
|
|
132
|
+
npm run build
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Additional commands:
|
|
136
|
+
|
|
137
|
+
- `npm run clean` remove `dist`
|
|
138
|
+
- `npm run test:all` run all tests
|
|
139
|
+
|
|
140
|
+
## Documentation Index
|
|
141
|
+
|
|
142
|
+
- `docs/API.md`: exported API reference
|
|
143
|
+
- `docs/MODULES.md`: module-by-module usage guide
|
|
144
|
+
- `docs/ARCHITECTURE.md`: system architecture and request flow
|
|
145
|
+
- `docs/SETUP.md`: setup, build, and test instructions
|
|
146
|
+
- `docs/CONFIGURATION.md`: request/session/CLI configuration
|
|
147
|
+
- `docs/ONBOARDING.md`: contributor onboarding guide
|
|
148
|
+
|
|
149
|
+
## Current Scope and Known Gaps
|
|
150
|
+
|
|
151
|
+
The project contains several lower-level modules that are present and tested in isolation but not fully integrated into the high-level request path yet.
|
|
152
|
+
|
|
153
|
+
- Proxy modules exist (`src/proxy/http-proxy.ts`, `src/proxy/socks.ts`), but `request.proxy` and `request.proxyAuth` are not currently applied by the protocol negotiator.
|
|
154
|
+
- Retry middleware helper exists (`src/middleware/retry.ts`), but session/client request execution does not currently invoke it.
|
|
155
|
+
- CLI `--cookie-jar` flag is parsed but not currently persisted to a cookie-jar file.
|
|
156
|
+
- `RequestTimings` fields are present in responses, but only partial timing data is currently populated by transport layers.
|
|
157
|
+
|
|
158
|
+
These behaviors are documented intentionally to prevent ambiguity in production integration.
|
|
159
|
+
|
|
160
|
+
## License
|
|
161
|
+
|
|
162
|
+
MIT. See `LICENSE`.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI argument parser.
|
|
3
|
+
*
|
|
4
|
+
* A zero-dependency argv parser tailored for nlcurl flags.
|
|
5
|
+
* Supports long flags (--flag value, --flag=value), short flags (-X GET),
|
|
6
|
+
* and boolean toggles (-k, --insecure).
|
|
7
|
+
*/
|
|
8
|
+
export interface ParsedArgs {
|
|
9
|
+
url: string;
|
|
10
|
+
method: string;
|
|
11
|
+
headers: Array<[string, string]>;
|
|
12
|
+
data: string | null;
|
|
13
|
+
dataRaw: string | null;
|
|
14
|
+
output: string | null;
|
|
15
|
+
impersonate: string | null;
|
|
16
|
+
ja3: string | null;
|
|
17
|
+
akamai: string | null;
|
|
18
|
+
stealth: boolean;
|
|
19
|
+
proxy: string | null;
|
|
20
|
+
proxyAuth: string | null;
|
|
21
|
+
insecure: boolean;
|
|
22
|
+
followRedirects: boolean;
|
|
23
|
+
maxRedirects: number;
|
|
24
|
+
timeout: number;
|
|
25
|
+
httpVersion: string | null;
|
|
26
|
+
verbose: boolean;
|
|
27
|
+
silent: boolean;
|
|
28
|
+
compressed: boolean;
|
|
29
|
+
head: boolean;
|
|
30
|
+
include: boolean;
|
|
31
|
+
listProfiles: boolean;
|
|
32
|
+
help: boolean;
|
|
33
|
+
version: boolean;
|
|
34
|
+
cookies: string | null;
|
|
35
|
+
cookieJar: string | null;
|
|
36
|
+
userAgent: string | null;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Parse CLI arguments into structured options.
|
|
40
|
+
*/
|
|
41
|
+
export declare function parseArgs(argv: string[]): ParsedArgs;
|
|
42
|
+
//# sourceMappingURL=args.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACjC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAiCD;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CAuLpD"}
|
package/dist/cli/args.js
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI argument parser.
|
|
3
|
+
*
|
|
4
|
+
* A zero-dependency argv parser tailored for nlcurl flags.
|
|
5
|
+
* Supports long flags (--flag value, --flag=value), short flags (-X GET),
|
|
6
|
+
* and boolean toggles (-k, --insecure).
|
|
7
|
+
*/
|
|
8
|
+
const DEFAULTS = {
|
|
9
|
+
url: '',
|
|
10
|
+
method: 'GET',
|
|
11
|
+
headers: [],
|
|
12
|
+
data: null,
|
|
13
|
+
dataRaw: null,
|
|
14
|
+
output: null,
|
|
15
|
+
impersonate: null,
|
|
16
|
+
ja3: null,
|
|
17
|
+
akamai: null,
|
|
18
|
+
stealth: false,
|
|
19
|
+
proxy: null,
|
|
20
|
+
proxyAuth: null,
|
|
21
|
+
insecure: false,
|
|
22
|
+
followRedirects: true,
|
|
23
|
+
maxRedirects: 20,
|
|
24
|
+
timeout: 30000,
|
|
25
|
+
httpVersion: null,
|
|
26
|
+
verbose: false,
|
|
27
|
+
silent: false,
|
|
28
|
+
compressed: false,
|
|
29
|
+
head: false,
|
|
30
|
+
include: false,
|
|
31
|
+
listProfiles: false,
|
|
32
|
+
help: false,
|
|
33
|
+
version: false,
|
|
34
|
+
cookies: null,
|
|
35
|
+
cookieJar: null,
|
|
36
|
+
userAgent: null,
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Parse CLI arguments into structured options.
|
|
40
|
+
*/
|
|
41
|
+
export function parseArgs(argv) {
|
|
42
|
+
const result = { ...DEFAULTS, headers: [] };
|
|
43
|
+
const args = argv.slice(2); // Skip node and script path
|
|
44
|
+
let i = 0;
|
|
45
|
+
while (i < args.length) {
|
|
46
|
+
const arg = args[i];
|
|
47
|
+
// Handle --flag=value syntax
|
|
48
|
+
if (arg.startsWith('--') && arg.includes('=')) {
|
|
49
|
+
const eqIdx = arg.indexOf('=');
|
|
50
|
+
const flag = arg.substring(0, eqIdx);
|
|
51
|
+
const value = arg.substring(eqIdx + 1);
|
|
52
|
+
processLongFlag(flag, value, result);
|
|
53
|
+
i++;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
switch (arg) {
|
|
57
|
+
// ---- Request configuration ----
|
|
58
|
+
case '-X':
|
|
59
|
+
case '--request':
|
|
60
|
+
result.method = requireNext(args, ++i, arg).toUpperCase();
|
|
61
|
+
break;
|
|
62
|
+
case '-H':
|
|
63
|
+
case '--header': {
|
|
64
|
+
const raw = requireNext(args, ++i, arg);
|
|
65
|
+
const colonIdx = raw.indexOf(':');
|
|
66
|
+
if (colonIdx > 0) {
|
|
67
|
+
result.headers.push([
|
|
68
|
+
raw.substring(0, colonIdx).trim(),
|
|
69
|
+
raw.substring(colonIdx + 1).trim(),
|
|
70
|
+
]);
|
|
71
|
+
}
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
case '-d':
|
|
75
|
+
case '--data':
|
|
76
|
+
case '--data-ascii':
|
|
77
|
+
result.data = requireNext(args, ++i, arg);
|
|
78
|
+
if (result.method === 'GET')
|
|
79
|
+
result.method = 'POST';
|
|
80
|
+
break;
|
|
81
|
+
case '--data-raw':
|
|
82
|
+
result.dataRaw = requireNext(args, ++i, arg);
|
|
83
|
+
if (result.method === 'GET')
|
|
84
|
+
result.method = 'POST';
|
|
85
|
+
break;
|
|
86
|
+
case '-A':
|
|
87
|
+
case '--user-agent':
|
|
88
|
+
result.userAgent = requireNext(args, ++i, arg);
|
|
89
|
+
break;
|
|
90
|
+
// ---- Output ----
|
|
91
|
+
case '-o':
|
|
92
|
+
case '--output':
|
|
93
|
+
result.output = requireNext(args, ++i, arg);
|
|
94
|
+
break;
|
|
95
|
+
case '-I':
|
|
96
|
+
case '--head':
|
|
97
|
+
result.head = true;
|
|
98
|
+
result.method = 'HEAD';
|
|
99
|
+
break;
|
|
100
|
+
case '-i':
|
|
101
|
+
case '--include':
|
|
102
|
+
result.include = true;
|
|
103
|
+
break;
|
|
104
|
+
case '-v':
|
|
105
|
+
case '--verbose':
|
|
106
|
+
result.verbose = true;
|
|
107
|
+
break;
|
|
108
|
+
case '-s':
|
|
109
|
+
case '--silent':
|
|
110
|
+
result.silent = true;
|
|
111
|
+
break;
|
|
112
|
+
case '--compressed':
|
|
113
|
+
result.compressed = true;
|
|
114
|
+
break;
|
|
115
|
+
// ---- Impersonation ----
|
|
116
|
+
case '--impersonate':
|
|
117
|
+
result.impersonate = requireNext(args, ++i, arg);
|
|
118
|
+
break;
|
|
119
|
+
case '--ja3':
|
|
120
|
+
result.ja3 = requireNext(args, ++i, arg);
|
|
121
|
+
break;
|
|
122
|
+
case '--akamai':
|
|
123
|
+
result.akamai = requireNext(args, ++i, arg);
|
|
124
|
+
break;
|
|
125
|
+
case '--stealth':
|
|
126
|
+
result.stealth = true;
|
|
127
|
+
break;
|
|
128
|
+
case '--list-profiles':
|
|
129
|
+
result.listProfiles = true;
|
|
130
|
+
break;
|
|
131
|
+
// ---- Connection ----
|
|
132
|
+
case '-x':
|
|
133
|
+
case '--proxy':
|
|
134
|
+
result.proxy = requireNext(args, ++i, arg);
|
|
135
|
+
break;
|
|
136
|
+
case '-U':
|
|
137
|
+
case '--proxy-user':
|
|
138
|
+
result.proxyAuth = requireNext(args, ++i, arg);
|
|
139
|
+
break;
|
|
140
|
+
case '-k':
|
|
141
|
+
case '--insecure':
|
|
142
|
+
result.insecure = true;
|
|
143
|
+
break;
|
|
144
|
+
case '-L':
|
|
145
|
+
case '--location':
|
|
146
|
+
result.followRedirects = true;
|
|
147
|
+
break;
|
|
148
|
+
case '--no-location':
|
|
149
|
+
result.followRedirects = false;
|
|
150
|
+
break;
|
|
151
|
+
case '--max-redirs':
|
|
152
|
+
result.maxRedirects = parseInt(requireNext(args, ++i, arg), 10);
|
|
153
|
+
break;
|
|
154
|
+
case '-m':
|
|
155
|
+
case '--max-time':
|
|
156
|
+
result.timeout = Math.round(parseFloat(requireNext(args, ++i, arg)) * 1000);
|
|
157
|
+
break;
|
|
158
|
+
case '--http1.1':
|
|
159
|
+
result.httpVersion = '1.1';
|
|
160
|
+
break;
|
|
161
|
+
case '--http2':
|
|
162
|
+
result.httpVersion = '2';
|
|
163
|
+
break;
|
|
164
|
+
// ---- Cookies ----
|
|
165
|
+
case '-b':
|
|
166
|
+
case '--cookie':
|
|
167
|
+
result.cookies = requireNext(args, ++i, arg);
|
|
168
|
+
break;
|
|
169
|
+
case '-c':
|
|
170
|
+
case '--cookie-jar':
|
|
171
|
+
result.cookieJar = requireNext(args, ++i, arg);
|
|
172
|
+
break;
|
|
173
|
+
// ---- Meta ----
|
|
174
|
+
case '-h':
|
|
175
|
+
case '--help':
|
|
176
|
+
result.help = true;
|
|
177
|
+
break;
|
|
178
|
+
case '-V':
|
|
179
|
+
case '--version':
|
|
180
|
+
result.version = true;
|
|
181
|
+
break;
|
|
182
|
+
default:
|
|
183
|
+
// Positional argument (URL)
|
|
184
|
+
if (!arg.startsWith('-') && !result.url) {
|
|
185
|
+
result.url = arg;
|
|
186
|
+
}
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
i++;
|
|
190
|
+
}
|
|
191
|
+
return result;
|
|
192
|
+
}
|
|
193
|
+
function requireNext(args, idx, flag) {
|
|
194
|
+
if (idx >= args.length) {
|
|
195
|
+
throw new Error(`Flag ${flag} requires a value`);
|
|
196
|
+
}
|
|
197
|
+
return args[idx];
|
|
198
|
+
}
|
|
199
|
+
function processLongFlag(flag, value, result) {
|
|
200
|
+
switch (flag) {
|
|
201
|
+
case '--impersonate':
|
|
202
|
+
result.impersonate = value;
|
|
203
|
+
break;
|
|
204
|
+
case '--ja3':
|
|
205
|
+
result.ja3 = value;
|
|
206
|
+
break;
|
|
207
|
+
case '--akamai':
|
|
208
|
+
result.akamai = value;
|
|
209
|
+
break;
|
|
210
|
+
case '--proxy':
|
|
211
|
+
result.proxy = value;
|
|
212
|
+
break;
|
|
213
|
+
case '--proxy-user':
|
|
214
|
+
result.proxyAuth = value;
|
|
215
|
+
break;
|
|
216
|
+
case '--max-redirs':
|
|
217
|
+
result.maxRedirects = parseInt(value, 10);
|
|
218
|
+
break;
|
|
219
|
+
case '--max-time':
|
|
220
|
+
result.timeout = Math.round(parseFloat(value) * 1000);
|
|
221
|
+
break;
|
|
222
|
+
case '--output':
|
|
223
|
+
result.output = value;
|
|
224
|
+
break;
|
|
225
|
+
case '--request':
|
|
226
|
+
result.method = value.toUpperCase();
|
|
227
|
+
break;
|
|
228
|
+
case '--user-agent':
|
|
229
|
+
result.userAgent = value;
|
|
230
|
+
break;
|
|
231
|
+
case '--cookie':
|
|
232
|
+
result.cookies = value;
|
|
233
|
+
break;
|
|
234
|
+
case '--cookie-jar':
|
|
235
|
+
result.cookieJar = value;
|
|
236
|
+
break;
|
|
237
|
+
case '--header': {
|
|
238
|
+
const colonIdx = value.indexOf(':');
|
|
239
|
+
if (colonIdx > 0) {
|
|
240
|
+
result.headers.push([
|
|
241
|
+
value.substring(0, colonIdx).trim(),
|
|
242
|
+
value.substring(colonIdx + 1).trim(),
|
|
243
|
+
]);
|
|
244
|
+
}
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
case '--data':
|
|
248
|
+
case '--data-ascii':
|
|
249
|
+
result.data = value;
|
|
250
|
+
if (result.method === 'GET')
|
|
251
|
+
result.method = 'POST';
|
|
252
|
+
break;
|
|
253
|
+
case '--data-raw':
|
|
254
|
+
result.dataRaw = value;
|
|
255
|
+
if (result.method === 'GET')
|
|
256
|
+
result.method = 'POST';
|
|
257
|
+
break;
|
|
258
|
+
default:
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
//# sourceMappingURL=args.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA;;;;GAIG"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* NLcURL CLI entry point.
|
|
4
|
+
*
|
|
5
|
+
* Usage: nlcurl [OPTIONS] <URL>
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'node:fs';
|
|
8
|
+
import * as process from 'node:process';
|
|
9
|
+
import { parseArgs } from './args.js';
|
|
10
|
+
import { formatOutput, formatVerboseRequest, printHelp } from './output.js';
|
|
11
|
+
import { request } from '../core/client.js';
|
|
12
|
+
import { listProfiles } from '../fingerprints/database.js';
|
|
13
|
+
async function main() {
|
|
14
|
+
const args = parseArgs(process.argv);
|
|
15
|
+
// ---- Meta commands ----
|
|
16
|
+
if (args.help) {
|
|
17
|
+
process.stdout.write(printHelp() + '\n');
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (args.version) {
|
|
21
|
+
const pkg = JSON.parse(fs.readFileSync(new URL('../../package.json', import.meta.url), 'utf8'));
|
|
22
|
+
process.stdout.write(`nlcurl ${pkg.version}\n`);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (args.listProfiles) {
|
|
26
|
+
const profiles = listProfiles();
|
|
27
|
+
for (const name of profiles) {
|
|
28
|
+
process.stdout.write(name + '\n');
|
|
29
|
+
}
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
// ---- Validate URL ----
|
|
33
|
+
if (!args.url) {
|
|
34
|
+
process.stderr.write('Error: No URL specified. Use --help for usage.\n');
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
// Prepend https:// if no scheme is given
|
|
38
|
+
let url = args.url;
|
|
39
|
+
if (!url.startsWith('http://') && !url.startsWith('https://')) {
|
|
40
|
+
url = 'https://' + url;
|
|
41
|
+
}
|
|
42
|
+
// ---- Build request ----
|
|
43
|
+
const headers = {};
|
|
44
|
+
for (const [key, value] of args.headers) {
|
|
45
|
+
headers[key] = value;
|
|
46
|
+
}
|
|
47
|
+
if (args.userAgent) {
|
|
48
|
+
headers['user-agent'] = args.userAgent;
|
|
49
|
+
}
|
|
50
|
+
if (args.compressed && !headers['accept-encoding']) {
|
|
51
|
+
headers['accept-encoding'] = 'gzip, deflate, br';
|
|
52
|
+
}
|
|
53
|
+
if (args.cookies) {
|
|
54
|
+
headers['cookie'] = args.cookies;
|
|
55
|
+
}
|
|
56
|
+
const body = args.data ?? args.dataRaw ?? undefined;
|
|
57
|
+
const req = {
|
|
58
|
+
url,
|
|
59
|
+
method: args.method,
|
|
60
|
+
headers: Object.keys(headers).length > 0 ? headers : undefined,
|
|
61
|
+
body,
|
|
62
|
+
impersonate: args.impersonate ?? undefined,
|
|
63
|
+
ja3: args.ja3 ?? undefined,
|
|
64
|
+
akamai: args.akamai ?? undefined,
|
|
65
|
+
stealth: args.stealth || undefined,
|
|
66
|
+
proxy: args.proxy ?? undefined,
|
|
67
|
+
insecure: args.insecure || undefined,
|
|
68
|
+
followRedirects: args.followRedirects,
|
|
69
|
+
maxRedirects: args.maxRedirects,
|
|
70
|
+
timeout: args.timeout,
|
|
71
|
+
httpVersion: args.httpVersion ?? undefined,
|
|
72
|
+
};
|
|
73
|
+
if (args.proxyAuth) {
|
|
74
|
+
const [user, pass] = args.proxyAuth.split(':');
|
|
75
|
+
if (user && pass) {
|
|
76
|
+
req.proxyAuth = [user, pass];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// ---- Verbose request output ----
|
|
80
|
+
if (args.verbose) {
|
|
81
|
+
const verboseReq = formatVerboseRequest(req.method ?? 'GET', url, headers);
|
|
82
|
+
process.stderr.write(verboseReq + '\n');
|
|
83
|
+
}
|
|
84
|
+
// ---- Execute request ----
|
|
85
|
+
try {
|
|
86
|
+
const response = await request(req);
|
|
87
|
+
const output = formatOutput(response, args);
|
|
88
|
+
if (args.output) {
|
|
89
|
+
fs.writeFileSync(args.output, response.rawBody);
|
|
90
|
+
if (!args.silent) {
|
|
91
|
+
process.stderr.write(`Written to ${args.output}\n`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
process.stdout.write(output);
|
|
96
|
+
// Add trailing newline if body doesn't end with one
|
|
97
|
+
if (output.length > 0 && !output.endsWith('\n')) {
|
|
98
|
+
process.stdout.write('\n');
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (!response.ok && !args.silent) {
|
|
102
|
+
process.exit(22);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
if (!args.silent) {
|
|
107
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
108
|
+
process.stderr.write(`nlcurl: ${message}\n`);
|
|
109
|
+
}
|
|
110
|
+
process.exit(1);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
main();
|
|
114
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC5E,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAG3D,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAErC,0BAA0B;IAE1B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,CAAC;QACzC,OAAO;IACT,CAAC;IAED,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,EAAE,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,oBAAoB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CACxE,CAAC;QACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;QAChD,OAAO;IACT,CAAC;IAED,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;QAChC,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;QACpC,CAAC;QACD,OAAO;IACT,CAAC;IAED,yBAAyB;IAEzB,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,yCAAyC;IACzC,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;IACnB,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9D,GAAG,GAAG,UAAU,GAAG,GAAG,CAAC;IACzB,CAAC;IAED,0BAA0B;IAE1B,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACvB,CAAC;IAED,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC;IACzC,CAAC;IAED,IAAI,IAAI,CAAC,UAAU,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,iBAAiB,CAAC,GAAG,mBAAmB,CAAC;IACnD,CAAC;IAED,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,OAAO,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC;IACnC,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,IAAI,SAAS,CAAC;IAEpD,MAAM,GAAG,GAAkB;QACzB,GAAG;QACH,MAAM,EAAE,IAAI,CAAC,MAAoB;QACjC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;QAC9D,IAAI;QACJ,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,SAAS;QAC1C,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,SAAS;QAC1B,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,SAAS;QAChC,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,SAAS;QAClC,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,SAAS;QAC9B,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,SAAS;QACpC,eAAe,EAAE,IAAI,CAAC,eAAe;QACrC,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,WAAW,EAAG,IAAI,CAAC,WAA2B,IAAI,SAAS;KAC5D,CAAC;IAEF,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/C,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;YACjB,GAAG,CAAC,SAAS,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,mCAAmC;IAEnC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,UAAU,GAAG,oBAAoB,CACrC,GAAG,CAAC,MAAM,IAAI,KAAK,EACnB,GAAG,EACH,OAAO,CACR,CAAC;QACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED,4BAA4B;IAE5B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAE5C,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;YAChD,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACjB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC7B,oDAAoD;YACpD,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAChD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,OAAO,IAAI,CAAC,CAAC;QAC/C,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI output formatting.
|
|
3
|
+
*/
|
|
4
|
+
import { NLcURLResponse } from '../core/response.js';
|
|
5
|
+
import type { ParsedArgs } from './args.js';
|
|
6
|
+
/**
|
|
7
|
+
* Format and write response output to stdout/stderr.
|
|
8
|
+
*/
|
|
9
|
+
export declare function formatOutput(response: NLcURLResponse, args: ParsedArgs): string;
|
|
10
|
+
/**
|
|
11
|
+
* Format the response status line and headers.
|
|
12
|
+
*/
|
|
13
|
+
export declare function formatResponseHeaders(response: NLcURLResponse): string;
|
|
14
|
+
/**
|
|
15
|
+
* Format verbose request info (written to stderr).
|
|
16
|
+
*/
|
|
17
|
+
export declare function formatVerboseRequest(method: string, url: string, headers: Record<string, string>): string;
|
|
18
|
+
/**
|
|
19
|
+
* Print the help text.
|
|
20
|
+
*/
|
|
21
|
+
export declare function printHelp(): string;
|
|
22
|
+
//# sourceMappingURL=output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/cli/output.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5C;;GAEG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,cAAc,EACxB,IAAI,EAAE,UAAU,GACf,MAAM,CAmBR;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAYtE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC9B,MAAM,CAaR;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,MAAM,CAmDlC"}
|