@maschinenlesbar.org/govdata-cli 0.0.2 → 0.0.4
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/README.md +189 -130
- package/dist/src/cli/program.js +2 -2
- package/dist/src/cli/program.js.map +1 -1
- package/dist/src/cli/shared.d.ts +8 -0
- package/dist/src/cli/shared.d.ts.map +1 -1
- package/dist/src/cli/shared.js +20 -0
- package/dist/src/cli/shared.js.map +1 -1
- package/dist/src/client/engine.d.ts.map +1 -1
- package/dist/src/client/engine.js +46 -1
- package/dist/src/client/engine.js.map +1 -1
- package/dist/src/client/http.d.ts.map +1 -1
- package/dist/src/client/http.js +27 -4
- package/dist/src/client/http.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,187 +1,246 @@
|
|
|
1
1
|
# govdata-cli
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
[
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
3
|
+
[](https://github.com/maschinenlesbar-org/govdata-cli/actions/workflows/ci.yml)
|
|
4
|
+
[](https://github.com/maschinenlesbar-org/govdata-cli/actions/workflows/release.yml)
|
|
5
|
+
[](https://www.npmjs.com/package/@maschinenlesbar.org/govdata-cli)
|
|
6
|
+
|
|
7
|
+
Browse Germany's central open-data catalogue from your terminal. `govdata` is a
|
|
8
|
+
command-line tool over the [GovData CKAN Action API](https://www.govdata.de/)
|
|
9
|
+
(`ckan.govdata.de`) — the national portal that federates open datasets from
|
|
10
|
+
federal government, federal states and municipalities: search, inspect, filter
|
|
11
|
+
and pipe straight into [`jq`](https://jqlang.github.io/jq/).
|
|
12
|
+
|
|
13
|
+
- **Works out of the box** — no account, no API key, no configuration. Install
|
|
14
|
+
and explore.
|
|
15
|
+
- **Clean JSON output** — the CKAN envelope is unwrapped for you; `--compact`
|
|
16
|
+
for one-line/scripting.
|
|
17
|
+
- **Ten commands** — `search`, `package`, `packages`, `organizations`,
|
|
18
|
+
`organization`, `groups`, `group`, `tags`, `resource`, and a generic `action`
|
|
19
|
+
escape hatch.
|
|
20
|
+
- **Everything is open** — every dataset this tool reaches is publicly licensed;
|
|
21
|
+
nothing to register for.
|
|
22
|
+
|
|
23
|
+
> Want to use this as a TypeScript library or understand how it's built?
|
|
24
|
+
> See **[DEVELOPING.md](DEVELOPING.md)**.
|
|
17
25
|
|
|
18
26
|
## Install
|
|
19
27
|
|
|
20
28
|
```bash
|
|
21
|
-
npm
|
|
22
|
-
npm run build # compiles TypeScript to dist/
|
|
29
|
+
npm i -g @maschinenlesbar.org/govdata-cli
|
|
23
30
|
```
|
|
24
31
|
|
|
25
|
-
|
|
32
|
+
This installs the **`govdata`** command. Requires **Node.js 20+**.
|
|
33
|
+
|
|
34
|
+
Check it works:
|
|
26
35
|
|
|
27
36
|
```bash
|
|
28
|
-
node dist/src/cli/index.js --help
|
|
29
|
-
# or, after `npm link` / global install:
|
|
30
37
|
govdata --help
|
|
31
38
|
```
|
|
32
39
|
|
|
33
|
-
|
|
40
|
+
## Quickstart
|
|
34
41
|
|
|
35
|
-
|
|
42
|
+
No setup needed — the API is open and requires no key. Your first search:
|
|
36
43
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
44
|
+
```bash
|
|
45
|
+
govdata search Haushalt --rows 5
|
|
46
|
+
```
|
|
40
47
|
|
|
41
|
-
|
|
48
|
+
The result is unwrapped from CKAN's `{ help, success, result }` envelope — you
|
|
49
|
+
get the search object directly: `{ count, results, sort, … }`. Pull out just
|
|
50
|
+
the titles with `jq`:
|
|
42
51
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
| `--max-retries <n>` | Retries for transient `429`/`503` responses (default `2`) |
|
|
49
|
-
| `--max-response-bytes <n>` | Cap response body size in bytes (`0` = unlimited; default 100 MiB) |
|
|
50
|
-
| `--compact` | Print JSON on a single line |
|
|
52
|
+
```bash
|
|
53
|
+
govdata search Haushalt --rows 5 | jq '{count, titles: [.results[].title]}'
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Take a name from those results and fetch the full dataset record:
|
|
51
57
|
|
|
52
|
-
|
|
53
|
-
|
|
58
|
+
```bash
|
|
59
|
+
govdata package luftqualitat
|
|
60
|
+
```
|
|
54
61
|
|
|
55
|
-
|
|
62
|
+
## Commands
|
|
56
63
|
|
|
57
64
|
```text
|
|
58
|
-
search [query] [
|
|
59
|
-
package <id>
|
|
60
|
-
packages [--limit] [--offset] list dataset names
|
|
61
|
-
organizations [--all-fields]
|
|
62
|
-
organization <id>
|
|
63
|
-
groups [--all-fields]
|
|
64
|
-
group <id>
|
|
65
|
-
tags [--query <substring>]
|
|
66
|
-
resource <id>
|
|
67
|
-
action <name> [--param key=value
|
|
65
|
+
search [query] [filters…] search datasets
|
|
66
|
+
package <id> show one dataset by id or name
|
|
67
|
+
packages [--limit <n>] [--offset <n>] list dataset names
|
|
68
|
+
organizations [--all-fields] list organizations (publishers)
|
|
69
|
+
organization <id> show one organization
|
|
70
|
+
groups [--all-fields] list groups (themes/categories)
|
|
71
|
+
group <id> show one group
|
|
72
|
+
tags [--query <substring>] list tags
|
|
73
|
+
resource <id> show one resource (distribution)
|
|
74
|
+
action <name> [--param key=value …] call any CKAN action (generic)
|
|
68
75
|
```
|
|
69
76
|
|
|
70
|
-
###
|
|
77
|
+
### `search` filters
|
|
71
78
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
79
|
+
| Flag | Meaning |
|
|
80
|
+
| --- | --- |
|
|
81
|
+
| `[query]` | free-text Solr query, e.g. `Haushalt` or `title:Klimaschutz` |
|
|
82
|
+
| `--fq <filter>` | Solr filter query, e.g. `organization:destatis` (repeatable) |
|
|
83
|
+
| `--rows <n>` | max results to return |
|
|
84
|
+
| `--start <n>` | zero-based offset for paging |
|
|
85
|
+
| `--sort <expr>` | Solr sort expression, e.g. `metadata_modified desc` |
|
|
86
|
+
|
|
87
|
+
> **Note on `--rows`** — GovData's Solr caps a single search at **1000 results**
|
|
88
|
+
> server-side. Asking for more (e.g. `--rows 100000`) is not an error — you simply
|
|
89
|
+
> get at most 1000 back, while `count` still reports the true total. Use `--start`
|
|
90
|
+
> to page beyond the first 1000.
|
|
91
|
+
|
|
92
|
+
> **Note on free-text matching** — the bare `[query]` is a Solr query, and Solr
|
|
93
|
+
> *tokenises* terms: a string like `abc12345` can match a dataset whose title
|
|
94
|
+
> contains `12345` (e.g. `1,2,3,4,5 …`). If you need an exact field match, scope
|
|
95
|
+
> the query (`title:Klimaschutz`) or add an `--fq` filter rather than relying on a
|
|
96
|
+
> bare keyword.
|
|
97
|
+
|
|
98
|
+
### `packages` flags
|
|
99
|
+
|
|
100
|
+
| Flag | Meaning |
|
|
101
|
+
| --- | --- |
|
|
102
|
+
| `--limit <n>` | max names to return |
|
|
103
|
+
| `--offset <n>` | number of records to skip |
|
|
75
104
|
|
|
76
|
-
|
|
77
|
-
govdata search --fq organization:destatis --fq res_format:CSV
|
|
105
|
+
### `organizations` / `groups` flag
|
|
78
106
|
|
|
79
|
-
|
|
80
|
-
|
|
107
|
+
| Flag | Meaning |
|
|
108
|
+
| --- | --- |
|
|
109
|
+
| `--all-fields` | return full objects instead of bare names |
|
|
81
110
|
|
|
82
|
-
|
|
83
|
-
govdata organizations
|
|
111
|
+
### `tags` flag
|
|
84
112
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
113
|
+
| Flag | Meaning |
|
|
114
|
+
| --- | --- |
|
|
115
|
+
| `--query <substring>` | filter tags by substring |
|
|
88
116
|
|
|
89
|
-
|
|
117
|
+
### `action` flag
|
|
90
118
|
|
|
91
|
-
|
|
119
|
+
| Flag | Meaning |
|
|
120
|
+
| --- | --- |
|
|
121
|
+
| `--param <key=value>` | query parameter (repeatable; duplicate keys are rejected) |
|
|
92
122
|
|
|
93
|
-
|
|
123
|
+
> **Note on the `<name>`** — the action name is validated client-side against
|
|
124
|
+
> `^[a-z0-9_]+$` (lowercase letters, digits and underscores). Names with dashes,
|
|
125
|
+
> uppercase letters or spaces are rejected before any request is sent — this keeps
|
|
126
|
+
> the escape hatch from injecting extra path segments into the request URL. Use the
|
|
127
|
+
> exact CKAN action name, e.g. `package_search`, `organization_list`, `status_show`.
|
|
94
128
|
|
|
95
|
-
|
|
96
|
-
|
|
129
|
+
The **[Glossary](GLOSSARY.md)** decodes every CKAN term and search-parameter
|
|
130
|
+
name.
|
|
97
131
|
|
|
98
|
-
|
|
132
|
+
## Common tasks
|
|
99
133
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const orgs = await client.organizationList();
|
|
134
|
+
A few recipes to get going — see **[Usage.md](Usage.md)** for the full,
|
|
135
|
+
use-case-driven set.
|
|
103
136
|
|
|
104
|
-
|
|
105
|
-
|
|
137
|
+
```bash
|
|
138
|
+
# Newest datasets first
|
|
139
|
+
govdata search Klima --rows 10 --sort "metadata_modified desc"
|
|
106
140
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
|
|
141
|
+
# Filter by publisher and file format
|
|
142
|
+
govdata search --fq organization:destatis --fq res_format:CSV
|
|
143
|
+
|
|
144
|
+
# Full dataset with all its resources (distributions)
|
|
145
|
+
govdata package luftqualitat | jq '.resources[] | {name, format, url}'
|
|
146
|
+
|
|
147
|
+
# All data publishers (short names)
|
|
148
|
+
govdata organizations
|
|
149
|
+
|
|
150
|
+
# Full publisher objects, then drill into one
|
|
151
|
+
govdata organizations --all-fields | jq '.[] | {name, title, packages: .package_count}'
|
|
152
|
+
govdata organization statistisches-bundesamt | jq '{title, package_count}'
|
|
113
153
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
timeoutMs: 15_000,
|
|
120
|
-
maxRetries: 3, // 429 / 503 are retried with linear backoff
|
|
121
|
-
maxResponseBytes: 50 << 20, // abort responses larger than 50 MiB (0 = unlimited)
|
|
122
|
-
userAgent: "my-app/1.0",
|
|
123
|
-
transport: customTransport, // inject your own HTTP transport
|
|
124
|
-
});
|
|
154
|
+
# Tags matching a substring
|
|
155
|
+
govdata tags --query energie
|
|
156
|
+
|
|
157
|
+
# Any CKAN action not covered by a dedicated command
|
|
158
|
+
govdata action package_search --param q=Verkehr --param rows=3
|
|
125
159
|
```
|
|
126
160
|
|
|
127
|
-
|
|
161
|
+
## Output & scripting
|
|
128
162
|
|
|
129
|
-
|
|
130
|
-
|
|
163
|
+
Every command prints the **unwrapped `result`** as pretty JSON to stdout.
|
|
164
|
+
Errors and diagnostics go to stderr, so piping stdout into `jq` stays clean.
|
|
131
165
|
|
|
132
|
-
|
|
166
|
+
```bash
|
|
167
|
+
# Total datasets in the catalogue
|
|
168
|
+
govdata action package_search --param rows=0 | jq '.count'
|
|
133
169
|
|
|
134
|
-
|
|
170
|
+
# Resource format and download URL from a dataset
|
|
171
|
+
govdata package luftqualitat | jq '.resources[] | {format, url}'
|
|
135
172
|
|
|
173
|
+
# Discover a valid dataset name from a search hit
|
|
174
|
+
govdata search Luftqualität --rows 1 | jq -r '.results[0].name'
|
|
136
175
|
```
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
engine.ts # URL building, retry/backoff, redirects, JSON decoding, error mapping
|
|
143
|
-
errors.ts # GovDataError / GovDataApiError / GovDataNetworkError / GovDataParseError
|
|
144
|
-
client.ts # GovDataClient — CKAN actions over the engine (with result-unwrapping)
|
|
145
|
-
cli/
|
|
146
|
-
io.ts # injectable I/O seam (stdout/stderr)
|
|
147
|
-
shared.ts # option parsers, global-option resolver, JSON renderer
|
|
148
|
-
commands/ # search / package / organizations / groups / tags / resource / action
|
|
149
|
-
program.ts # assembles the commander program from injectable deps
|
|
150
|
-
run.ts # parses argv -> exit code (no process.exit; testable)
|
|
151
|
-
index.ts # #! bin shim
|
|
176
|
+
|
|
177
|
+
Use `--compact` for single-line JSON in pipelines and logs:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
govdata --compact search Haushalt --rows 5 | jq -c '.results[].title'
|
|
152
181
|
```
|
|
153
182
|
|
|
154
|
-
**
|
|
183
|
+
`--compact` (and every global option) works **before or after** the command —
|
|
184
|
+
both `govdata --compact search …` and `govdata search … --compact` do the same
|
|
185
|
+
thing.
|
|
186
|
+
|
|
187
|
+
**Exit codes** make the CLI easy to use in scripts:
|
|
155
188
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
- Redirects are followed up to `maxRedirects`; if a redirect crosses origin, the request headers are dropped so nothing (e.g. a future auth/cookie header) leaks to another host.
|
|
189
|
+
| Code | Meaning |
|
|
190
|
+
| --- | --- |
|
|
191
|
+
| `0` | success (also `--help` / `--version`) |
|
|
192
|
+
| `4` | dataset/resource not found (`404`) |
|
|
193
|
+
| `1` | any other error — bad usage, CKAN `success:false`, network failure |
|
|
162
194
|
|
|
163
|
-
|
|
195
|
+
## Troubleshooting
|
|
164
196
|
|
|
165
|
-
|
|
197
|
+
- **`command not found: govdata`** — the global npm bin directory isn't on your
|
|
198
|
+
`PATH`. Run `npm bin -g` to find it and add it, or run via
|
|
199
|
+
`npx @maschinenlesbar.org/govdata-cli …`.
|
|
200
|
+
- **Exit `4` / "not found"** — the dataset or resource id doesn't exist or has
|
|
201
|
+
been removed. Re-run a `search` to get a fresh name/id.
|
|
202
|
+
- **Exit `1` / CKAN `success:false`** — the catalogue rejected the request
|
|
203
|
+
(malformed filter, unknown action name, etc.). Check your `--fq` syntax or
|
|
204
|
+
`--param` values.
|
|
205
|
+
- **Network failure / timeout** — connectivity or a slow server. Try again, or
|
|
206
|
+
raise the limit with `--timeout 60000`.
|
|
207
|
+
- **Empty `results`** — the search matched nothing; broaden the keyword, drop
|
|
208
|
+
an `--fq` filter, or check spelling.
|
|
166
209
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
210
|
+
## Global options
|
|
211
|
+
|
|
212
|
+
These apply to every command and may be given before *or* after it:
|
|
213
|
+
|
|
214
|
+
| Option | Description |
|
|
215
|
+
| --- | --- |
|
|
216
|
+
| `-V, --version` | Print the version number |
|
|
217
|
+
| `-h, --help` | Show help for the program or a command |
|
|
218
|
+
| `--compact` | Print JSON on a single line instead of pretty-printed |
|
|
219
|
+
| `--base-url <url>` | API base URL (default `https://ckan.govdata.de`) |
|
|
220
|
+
| `--timeout <ms>` | Per-request timeout (default `30000`) |
|
|
221
|
+
| `--user-agent <ua>` | `User-Agent` header value |
|
|
222
|
+
| `--max-retries <n>` | Retries for transient `429`/`503` responses (default `2`) |
|
|
223
|
+
| `--max-response-bytes <n>` | Cap response body size in bytes (`0` = unlimited; default 100 MiB) |
|
|
224
|
+
|
|
225
|
+
## Learn more
|
|
170
226
|
|
|
171
|
-
-
|
|
172
|
-
-
|
|
173
|
-
|
|
174
|
-
-
|
|
175
|
-
|
|
227
|
+
- **[Usage.md](Usage.md)** — full use-case-driven cookbook.
|
|
228
|
+
- **[GLOSSARY.md](GLOSSARY.md)** — every CKAN term, search parameter and domain
|
|
229
|
+
concept explained.
|
|
230
|
+
- **[DEVELOPING.md](DEVELOPING.md)** — TypeScript library usage, architecture,
|
|
231
|
+
testing, CI.
|
|
232
|
+
- **[SKILLS.md](SKILLS.md)** — Claude Code Agent Skills bundled with this repo
|
|
233
|
+
(dataset finder, catalogue stats, resource harvest), installable as a plugin.
|
|
176
234
|
|
|
177
|
-
##
|
|
235
|
+
## Data license
|
|
178
236
|
|
|
179
|
-
|
|
237
|
+
This CLI is a **client** — it accesses data it does not own or redistribute. The
|
|
238
|
+
upstream data is © its provider and licensed **separately from this tool's code**.
|
|
239
|
+
See **[DATA_LICENSE.md](DATA_LICENSE.md)**.
|
|
180
240
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
- **docs.yml** — build TypeDoc API docs and deploy to GitHub Pages on each `v*` tag.
|
|
241
|
+
> **GovData** — catalogue *metadata* is Datenlizenz Deutschland **Zero** 2.0 (≈ CC0,
|
|
242
|
+
> no attribution). Each linked **dataset has its own license** set by its publisher
|
|
243
|
+
> — always check the dataset's `dct:license` before reusing its contents.
|
|
185
244
|
|
|
186
245
|
## License
|
|
187
246
|
|
package/dist/src/cli/program.js
CHANGED
|
@@ -6,7 +6,7 @@ import { fileURLToPath } from "node:url";
|
|
|
6
6
|
import { Command } from "commander";
|
|
7
7
|
import { defaultIO } from "./io.js";
|
|
8
8
|
import { GovDataClient } from "../client/client.js";
|
|
9
|
-
import { parseIntArg } from "./shared.js";
|
|
9
|
+
import { parseBaseUrl, parseIntArg } from "./shared.js";
|
|
10
10
|
import { registerCatalogueCommands } from "./commands/catalogue.js";
|
|
11
11
|
/**
|
|
12
12
|
* Single source of truth for the version: read from package.json at runtime
|
|
@@ -36,7 +36,7 @@ export function buildProgram(deps = defaultDeps) {
|
|
|
36
36
|
.name("govdata")
|
|
37
37
|
.description("CLI for the open GovData CKAN catalogue API (https://ckan.govdata.de/api/3/action)")
|
|
38
38
|
.version(VERSION)
|
|
39
|
-
.option("--base-url <url>", "API base URL", "https://ckan.govdata.de")
|
|
39
|
+
.option("--base-url <url>", "API base URL", parseBaseUrl, "https://ckan.govdata.de")
|
|
40
40
|
.option("--timeout <ms>", "per-request timeout in milliseconds", parseIntArg)
|
|
41
41
|
.option("--user-agent <ua>", "User-Agent header value")
|
|
42
42
|
.option("--max-retries <n>", "retries for transient 429/503 responses", parseIntArg)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"program.js","sourceRoot":"","sources":["../../../src/cli/program.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,4EAA4E;AAC5E,mBAAmB;AAEnB,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"program.js","sourceRoot":"","sources":["../../../src/cli/program.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,4EAA4E;AAC5E,mBAAmB;AAEnB,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAEpE;;;;;GAKG;AACH,SAAS,WAAW;IAClB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,uBAAuB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAyB,CAAC;QAC5F,OAAO,GAAG,CAAC,OAAO,IAAI,OAAO,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;AAErC,yEAAyE;AACzE,MAAM,CAAC,MAAM,WAAW,GAAY;IAClC,EAAE,EAAE,SAAS;IACb,YAAY,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,aAAa,CAAC,OAAO,CAAC;CACtD,CAAC;AAEF,MAAM,UAAU,YAAY,CAAC,OAAgB,WAAW;IACtD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,SAAS,CAAC;SACf,WAAW,CACV,oFAAoF,CACrF;SACA,OAAO,CAAC,OAAO,CAAC;SAChB,MAAM,CAAC,kBAAkB,EAAE,cAAc,EAAE,YAAY,EAAE,yBAAyB,CAAC;SACnF,MAAM,CAAC,gBAAgB,EAAE,qCAAqC,EAAE,WAAW,CAAC;SAC5E,MAAM,CAAC,mBAAmB,EAAE,yBAAyB,CAAC;SACtD,MAAM,CAAC,mBAAmB,EAAE,yCAAyC,EAAE,WAAW,CAAC;SACnF,MAAM,CACL,0BAA0B,EAC1B,kEAAkE,EAClE,WAAW,CACZ;SACA,MAAM,CAAC,WAAW,EAAE,uDAAuD,CAAC;SAC5E,kBAAkB,EAAE,CAAC;IAExB,4EAA4E;IAC5E,+EAA+E;IAC/E,0EAA0E;IAC1E,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE;QAClB,OAAO,CAAC,IAAI,EAAE,CAAC;IACjB,CAAC,CAAC,CAAC;IAEH,yBAAyB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAEzC,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
package/dist/src/cli/shared.d.ts
CHANGED
|
@@ -2,6 +2,14 @@ import type { CliDeps } from "./io.js";
|
|
|
2
2
|
import type { EngineOptions } from "../client/engine.js";
|
|
3
3
|
/** commander value-parser: a non-negative integer. */
|
|
4
4
|
export declare function parseIntArg(value: string): number;
|
|
5
|
+
/**
|
|
6
|
+
* commander value-parser for --base-url: reject a non-http(s) scheme at parse
|
|
7
|
+
* time so `file:`, `ftp:`, etc. fail fast with a usage error rather than only
|
|
8
|
+
* being caught later in the transport. The default transport also re-checks the
|
|
9
|
+
* scheme per hop (and RequestEngine.buildUrl guards it for custom transports),
|
|
10
|
+
* but this surfaces the mistake up front and independently of the transport.
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseBaseUrl(value: string): string;
|
|
5
13
|
export interface GlobalOptions {
|
|
6
14
|
baseUrl?: string;
|
|
7
15
|
timeout?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/cli/shared.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,sDAAsD;AACtD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAajD;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,uEAAuE;AACvE,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,CAQpE;AAED,gFAAgF;AAChF,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAGrF;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC;IAC5C,MAAM,EAAE,aAAa,CAAC;IACtB,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED;;;;;;;GAOG;AACH,wBAAgB,MAAM,CACpB,IAAI,EAAE,OAAO,EACb,EAAE,EAAE,CAAC,GAAG,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAC/D,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAQvC"}
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/cli/shared.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,sDAAsD;AACtD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAajD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAalD;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,uEAAuE;AACvE,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,CAQpE;AAED,gFAAgF;AAChF,wBAAgB,UAAU,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAGrF;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC;IAC5C,MAAM,EAAE,aAAa,CAAC;IACtB,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED;;;;;;;GAOG;AACH,wBAAgB,MAAM,CACpB,IAAI,EAAE,OAAO,EACb,EAAE,EAAE,CAAC,GAAG,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GAC/D,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAQvC"}
|
package/dist/src/cli/shared.js
CHANGED
|
@@ -16,6 +16,26 @@ export function parseIntArg(value) {
|
|
|
16
16
|
}
|
|
17
17
|
return n;
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* commander value-parser for --base-url: reject a non-http(s) scheme at parse
|
|
21
|
+
* time so `file:`, `ftp:`, etc. fail fast with a usage error rather than only
|
|
22
|
+
* being caught later in the transport. The default transport also re-checks the
|
|
23
|
+
* scheme per hop (and RequestEngine.buildUrl guards it for custom transports),
|
|
24
|
+
* but this surfaces the mistake up front and independently of the transport.
|
|
25
|
+
*/
|
|
26
|
+
export function parseBaseUrl(value) {
|
|
27
|
+
let url;
|
|
28
|
+
try {
|
|
29
|
+
url = new URL(value);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
throw new InvalidArgumentError("Expected an absolute http(s) URL.");
|
|
33
|
+
}
|
|
34
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
35
|
+
throw new InvalidArgumentError(`Unsupported scheme "${url.protocol}". Expected an http(s) URL.`);
|
|
36
|
+
}
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
19
39
|
/** Translate resolved global CLI options into client EngineOptions. */
|
|
20
40
|
export function toEngineOptions(global) {
|
|
21
41
|
const options = {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/cli/shared.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,iDAAiD;AAGjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAIjD,sDAAsD;AACtD,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,yEAAyE;IACzE,2EAA2E;IAC3E,yDAAyD;IACzD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,oBAAoB,CAAC,kCAAkC,CAAC,CAAC;IACrE,CAAC;IACD,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACxB,gFAAgF;IAChF,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,oBAAoB,CAAC,kCAAkC,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAWD,uEAAuE;AACvE,MAAM,UAAU,eAAe,CAAC,MAAqB;IACnD,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IACnE,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,CAAC,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC;IACrE,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS;QAAE,OAAO,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;IACzE,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS;QAAE,OAAO,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IAC5E,IAAI,MAAM,CAAC,gBAAgB,KAAK,SAAS;QAAE,OAAO,CAAC,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,CAAC;IAC9F,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,UAAU,CAAC,IAAa,EAAE,MAAqB,EAAE,KAAc;IAC7E,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACrF,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACpB,CAAC;AASD;;;;;;;GAOG;AACH,MAAM,UAAU,MAAM,CACpB,IAAa,EACb,EAAgE;IAEhE,OAAO,KAAK,EAAE,GAAG,IAAe,EAAE,EAAE;QAClC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAY,CAAC;QACjD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAa,CAAC;QAC5E,MAAM,MAAM,GAAG,OAAO,CAAC,eAAe,EAAmB,CAAC;QAC1D,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1D,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC;IAClE,CAAC,CAAC;AACJ,CAAC"}
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/cli/shared.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,iDAAiD;AAGjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAIjD,sDAAsD;AACtD,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,yEAAyE;IACzE,2EAA2E;IAC3E,yDAAyD;IACzD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,oBAAoB,CAAC,kCAAkC,CAAC,CAAC;IACrE,CAAC;IACD,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACxB,gFAAgF;IAChF,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,oBAAoB,CAAC,kCAAkC,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,oBAAoB,CAAC,mCAAmC,CAAC,CAAC;IACtE,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1D,MAAM,IAAI,oBAAoB,CAC5B,uBAAuB,GAAG,CAAC,QAAQ,6BAA6B,CACjE,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAWD,uEAAuE;AACvE,MAAM,UAAU,eAAe,CAAC,MAAqB;IACnD,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IACnE,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,CAAC,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC;IACrE,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS;QAAE,OAAO,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;IACzE,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS;QAAE,OAAO,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IAC5E,IAAI,MAAM,CAAC,gBAAgB,KAAK,SAAS;QAAE,OAAO,CAAC,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,CAAC;IAC9F,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,UAAU,CAAC,IAAa,EAAE,MAAqB,EAAE,KAAc;IAC7E,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACrF,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACpB,CAAC;AASD;;;;;;;GAOG;AACH,MAAM,UAAU,MAAM,CACpB,IAAa,EACb,EAAgE;IAEhE,OAAO,KAAK,EAAE,GAAG,IAAe,EAAE,EAAE;QAClC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAY,CAAC;QACjD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAa,CAAC;QAC5E,MAAM,MAAM,GAAG,OAAO,CAAC,eAAe,EAAmB,CAAC;QAC1D,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1D,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC;IAClE,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/client/engine.ts"],"names":[],"mappings":"AAIA,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAGhE,eAAO,MAAM,gBAAgB,4BAA4B,CAAC;AAG1D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2DAA2D;IAC3D,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/client/engine.ts"],"names":[],"mappings":"AAIA,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAGhE,eAAO,MAAM,gBAAgB,4BAA4B,CAAC;AAG1D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2DAA2D;IAC3D,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AA8CD,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgC;gBAE1C,OAAO,GAAE,aAAkB;IAgBvC,6EAA6E;IAC7E,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,MAAM;IAMnD,6EAA6E;IACvE,OAAO,CACX,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,WAAW,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAmC,GAChF,OAAO,CAAC,WAAW,CAAC;IAuDvB,0DAA0D;IACpD,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;IAU/D,OAAO,CAAC,UAAU;CAoCnB"}
|
|
@@ -3,10 +3,47 @@
|
|
|
3
3
|
// (429, 503), and decodes responses.
|
|
4
4
|
import { nodeHttpTransport } from "./http.js";
|
|
5
5
|
import { buildQueryString } from "./query.js";
|
|
6
|
-
import { GovDataApiError, GovDataParseError } from "./errors.js";
|
|
6
|
+
import { GovDataApiError, GovDataNetworkError, GovDataParseError } from "./errors.js";
|
|
7
7
|
export const DEFAULT_BASE_URL = "https://ckan.govdata.de";
|
|
8
8
|
const DEFAULT_USER_AGENT = "govdata-cli";
|
|
9
9
|
const DEFAULT_MAX_RESPONSE_BYTES = 100 * 1024 * 1024;
|
|
10
|
+
/**
|
|
11
|
+
* Strip control characters (all C0/C1 controls except tab and newline, plus DEL)
|
|
12
|
+
* out of a string that originates in an attacker-controlled response — the error
|
|
13
|
+
* `detail` extracted from the body. `JSON.parse` decodes an escaped ESC in an
|
|
14
|
+
* error body into a real ESC byte, so without this a hostile/MITM'd endpoint could
|
|
15
|
+
* drive ANSI/OSC escape sequences into the user's terminal when the message is
|
|
16
|
+
* printed to stderr. The success path is already safe (`JSON.stringify` escapes
|
|
17
|
+
* these), so this only needs to cover text that flows into an error message.
|
|
18
|
+
*/
|
|
19
|
+
function sanitizeServerText(text) {
|
|
20
|
+
let out = "";
|
|
21
|
+
for (const ch of text) {
|
|
22
|
+
const n = ch.codePointAt(0) ?? 0;
|
|
23
|
+
if (n <= 8 || (n >= 0x0b && n <= 0x1f) || (n >= 0x7f && n <= 0x9f))
|
|
24
|
+
continue;
|
|
25
|
+
out += ch;
|
|
26
|
+
}
|
|
27
|
+
return out;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Reject a base URL whose scheme is not http(s). The default transport already
|
|
31
|
+
* gates this per hop, but the engine is exported as a library and may be handed a
|
|
32
|
+
* custom transport that does no such check, so gate the configured base URL here
|
|
33
|
+
* too (a `file:`/`ftp:` base URL fails fast with a typed error).
|
|
34
|
+
*/
|
|
35
|
+
function assertHttpScheme(baseUrl) {
|
|
36
|
+
let url;
|
|
37
|
+
try {
|
|
38
|
+
url = new URL(baseUrl);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
throw new GovDataNetworkError(`Invalid base URL: ${baseUrl}`);
|
|
42
|
+
}
|
|
43
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") {
|
|
44
|
+
throw new GovDataNetworkError(`Unsupported protocol "${url.protocol}" in base URL: ${baseUrl}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
10
47
|
const realSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
11
48
|
export class RequestEngine {
|
|
12
49
|
baseUrl;
|
|
@@ -20,6 +57,10 @@ export class RequestEngine {
|
|
|
20
57
|
sleep;
|
|
21
58
|
constructor(options = {}) {
|
|
22
59
|
this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
|
|
60
|
+
// Re-check the base-URL scheme here, not only in the default transport: a
|
|
61
|
+
// library consumer that injects a custom transport would otherwise get no
|
|
62
|
+
// gating at all, and could be steered to a non-http(s) scheme.
|
|
63
|
+
assertHttpScheme(this.baseUrl);
|
|
23
64
|
this.transport = options.transport ?? nodeHttpTransport;
|
|
24
65
|
this.userAgent = options.userAgent ?? DEFAULT_USER_AGENT;
|
|
25
66
|
this.timeoutMs = options.timeoutMs ?? 30_000;
|
|
@@ -126,6 +167,10 @@ export class RequestEngine {
|
|
|
126
167
|
catch {
|
|
127
168
|
// Non-JSON error body; leave detail undefined.
|
|
128
169
|
}
|
|
170
|
+
// `detail` came from the response body; strip control characters so a hostile
|
|
171
|
+
// endpoint cannot inject terminal escape sequences via the stderr error message.
|
|
172
|
+
if (detail !== undefined)
|
|
173
|
+
detail = sanitizeServerText(detail);
|
|
129
174
|
return new GovDataApiError({ status, url, method, body: text, detail });
|
|
130
175
|
}
|
|
131
176
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/client/engine.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,yEAAyE;AACzE,qCAAqC;AAErC,OAAO,EAAE,iBAAiB,EAAkB,MAAM,WAAW,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAoB,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/client/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../src/client/http.ts"],"names":[],"mappings":"AAQA,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mFAAmF;IACnF,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,IAAI,CAAC,mBAAmB,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;AAExE;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../src/client/http.ts"],"names":[],"mappings":"AAQA,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,kDAAkD;IAClD,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mFAAmF;IACnF,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,IAAI,CAAC,mBAAmB,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;AAExE;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,EAAE,SAgG5B,CAAC"}
|
package/dist/src/client/http.js
CHANGED
|
@@ -32,6 +32,19 @@ export const nodeHttpTransport = (request) => new Promise((resolve, reject) => {
|
|
|
32
32
|
const isHttps = url.protocol === "https:";
|
|
33
33
|
const driver = isHttps ? https : http;
|
|
34
34
|
const maxBytes = request.maxResponseBytes;
|
|
35
|
+
// Wall-clock deadline (see below). Declared here so both the settle wrappers
|
|
36
|
+
// and the request setup can reference it; cleared on the first settle.
|
|
37
|
+
let deadline;
|
|
38
|
+
const settleResolve = (value) => {
|
|
39
|
+
if (deadline)
|
|
40
|
+
clearTimeout(deadline);
|
|
41
|
+
resolve(value);
|
|
42
|
+
};
|
|
43
|
+
const settleReject = (err) => {
|
|
44
|
+
if (deadline)
|
|
45
|
+
clearTimeout(deadline);
|
|
46
|
+
reject(err);
|
|
47
|
+
};
|
|
35
48
|
const req = driver.request(url, {
|
|
36
49
|
method: request.method,
|
|
37
50
|
headers: request.headers,
|
|
@@ -46,7 +59,7 @@ export const nodeHttpTransport = (request) => new Promise((resolve, reject) => {
|
|
|
46
59
|
if (maxBytes !== undefined && received > maxBytes) {
|
|
47
60
|
aborted = true;
|
|
48
61
|
res.destroy();
|
|
49
|
-
|
|
62
|
+
settleReject(new GovDataNetworkError(`Response exceeded maxResponseBytes (${maxBytes})`));
|
|
50
63
|
return;
|
|
51
64
|
}
|
|
52
65
|
chunks.push(chunk);
|
|
@@ -54,7 +67,7 @@ export const nodeHttpTransport = (request) => new Promise((resolve, reject) => {
|
|
|
54
67
|
res.on("end", () => {
|
|
55
68
|
if (aborted)
|
|
56
69
|
return;
|
|
57
|
-
|
|
70
|
+
settleResolve({
|
|
58
71
|
status: res.statusCode ?? 0,
|
|
59
72
|
headers: res.headers,
|
|
60
73
|
body: Buffer.concat(chunks),
|
|
@@ -63,17 +76,27 @@ export const nodeHttpTransport = (request) => new Promise((resolve, reject) => {
|
|
|
63
76
|
res.on("error", (err) => {
|
|
64
77
|
if (aborted)
|
|
65
78
|
return; // we already rejected with the size-cap error
|
|
66
|
-
|
|
79
|
+
settleReject(new GovDataNetworkError(`Response stream error: ${err.message}`, { cause: err }));
|
|
67
80
|
});
|
|
68
81
|
});
|
|
69
82
|
if (request.timeoutMs && request.timeoutMs > 0) {
|
|
83
|
+
// Two complementary guards, both using timeoutMs:
|
|
84
|
+
// - setTimeout: a socket-*inactivity* timeout (no bytes for timeoutMs).
|
|
85
|
+
// - deadline: an overall *wall-clock* deadline, so a server that
|
|
86
|
+
// trickles one byte just under the inactivity window can't keep the
|
|
87
|
+
// request alive forever. Whichever trips first destroys the request.
|
|
70
88
|
req.setTimeout(request.timeoutMs, () => {
|
|
71
89
|
req.destroy(new GovDataNetworkError(`Request timed out after ${request.timeoutMs}ms`));
|
|
72
90
|
});
|
|
91
|
+
deadline = setTimeout(() => {
|
|
92
|
+
req.destroy(new GovDataNetworkError(`Request exceeded the ${request.timeoutMs}ms deadline`));
|
|
93
|
+
}, request.timeoutMs);
|
|
94
|
+
// Don't let a pending deadline timer keep the event loop alive on its own.
|
|
95
|
+
deadline.unref?.();
|
|
73
96
|
}
|
|
74
97
|
req.on("error", (err) => {
|
|
75
98
|
// A timeout destroy already passes an GovDataNetworkError; don't double-wrap.
|
|
76
|
-
|
|
99
|
+
settleReject(err instanceof GovDataNetworkError ? err : new GovDataNetworkError(err.message, { cause: err }));
|
|
77
100
|
});
|
|
78
101
|
if (request.body !== undefined)
|
|
79
102
|
req.write(request.body);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/client/http.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,iDAAiD;AACjD,EAAE;AACF,gFAAgF;AAChF,8EAA8E;AAC9E,8EAA8E;AAC9E,yCAAyC;AAEzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,KAAK,MAAM,YAAY,CAAC;AAC/B,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAuBlD;;;;GAIG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAc,CAAC,OAAO,EAAE,EAAE,CACtD,IAAI,OAAO,CAAe,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;IAC5C,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,IAAI,mBAAmB,CAAC,gBAAgB,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC/D,OAAO;IACT,CAAC;IAED,6EAA6E;IAC7E,2EAA2E;IAC3E,2DAA2D;IAC3D,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1D,MAAM,CAAC,IAAI,mBAAmB,CAAC,yBAAyB,GAAG,CAAC,QAAQ,aAAa,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACjG,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,KAAK,QAAQ,CAAC;IAC1C,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;IACtC,MAAM,QAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAE1C,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CACxB,GAAG,EACH;QACE,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,EACD,CAAC,GAAG,EAAE,EAAE;QACN,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,IAAI,OAAO,GAAG,KAAK,CAAC;QAEpB,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YAC/B,IAAI,OAAO;gBAAE,OAAO;YACpB,QAAQ,IAAI,KAAK,CAAC,MAAM,CAAC;YACzB,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,GAAG,QAAQ,EAAE,CAAC;gBAClD,OAAO,GAAG,IAAI,CAAC;gBACf,GAAG,CAAC,OAAO,EAAE,CAAC;gBACd,
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/client/http.ts"],"names":[],"mappings":"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"}
|