@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 CHANGED
@@ -1,187 +1,246 @@
1
1
  # govdata-cli
2
2
 
3
- A TypeScript **API client** and **command-line interface** for the open
4
- [GovData](https://www.govdata.de/) **CKAN Action API** (`ckan.govdata.de`) — the
5
- central German open-data catalogue (Bund/Länder/Kommunen): search datasets,
6
- inspect packages, organizations, groups, tags and resources.
7
-
8
- - **Zero runtime HTTP dependencies** built on Node's built-in `http`/`https` (no axios, no fetch polyfill).
9
- - **One small dependency** for the CLI: [`commander`](https://github.com/tj/commander.js).
10
- - **Strongly typed** — typed CKAN envelope, search result and parameter objects, plus a generic `action` escape hatch.
11
- - **Well tested** unit tests on Node's built-in test runner (`node --test`), every HTTP response mocked.
12
- - **Read-only, no auth** — only CKAN read actions are wrapped; no key required.
13
-
14
- ## Requirements
15
-
16
- - Node.js **>= 20** (uses the stable built-in test runner, ESM and top-level `await`).
3
+ [![CI](https://github.com/maschinenlesbar-org/govdata-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/maschinenlesbar-org/govdata-cli/actions/workflows/ci.yml)
4
+ [![Release](https://github.com/maschinenlesbar-org/govdata-cli/actions/workflows/release.yml/badge.svg)](https://github.com/maschinenlesbar-org/govdata-cli/actions/workflows/release.yml)
5
+ [![npm](https://img.shields.io/npm/v/@maschinenlesbar.org/govdata-cli)](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 install
22
- npm run build # compiles TypeScript to dist/
29
+ npm i -g @maschinenlesbar.org/govdata-cli
23
30
  ```
24
31
 
25
- Run the CLI without a global install:
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
- ## CLI usage
42
+ No setup needed — the API is open and requires no key. Your first search:
36
43
 
37
- CKAN wraps every response in `{ help, success, result }`; this CLI prints the
38
- unwrapped **`result`** (and exits non-zero if `success` is false). `--compact` for
39
- a single line.
44
+ ```bash
45
+ govdata search Haushalt --rows 5
46
+ ```
40
47
 
41
- ### Global options
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
- | Option | Description |
44
- | --- | --- |
45
- | `--base-url <url>` | API base URL (default `https://ckan.govdata.de`) |
46
- | `--timeout <ms>` | Per-request timeout (default `30000`) |
47
- | `--user-agent <ua>` | `User-Agent` header value |
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
- Global options may be given before or after the command, e.g.
53
- `govdata --compact search Haushalt` or `govdata search Haushalt --compact`.
58
+ ```bash
59
+ govdata package luftqualitat
60
+ ```
54
61
 
55
- ### Commands
62
+ ## Commands
56
63
 
57
64
  ```text
58
- search [query] [--rows <n>] [--start <n>] [--sort <expr>] [--fq <filter> ...]
59
- package <id> show one dataset
60
- packages [--limit] [--offset] list dataset names
61
- organizations [--all-fields] list organizations (publishers)
62
- organization <id> show one organization
63
- groups [--all-fields] list groups (themes)
64
- group <id> show one group
65
- tags [--query <substring>] list tags
66
- resource <id> show one resource (distribution)
67
- action <name> [--param key=value ...] call any CKAN action (generic)
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
- ### Examples
77
+ ### `search` filters
71
78
 
72
- ```bash
73
- # Search datasets, newest first
74
- govdata search Haushalt --rows 5 --sort "metadata_modified desc"
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
- # Filter by organization and format
77
- govdata search --fq organization:destatis --fq res_format:CSV
105
+ ### `organizations` / `groups` flag
78
106
 
79
- # A specific dataset
80
- govdata package <dataset-id-or-name>
107
+ | Flag | Meaning |
108
+ | --- | --- |
109
+ | `--all-fields` | return full objects instead of bare names |
81
110
 
82
- # Publishers
83
- govdata organizations
111
+ ### `tags` flag
84
112
 
85
- # Any action not wrapped above
86
- govdata action package_search --param q=Klima --param rows=3
87
- ```
113
+ | Flag | Meaning |
114
+ | --- | --- |
115
+ | `--query <substring>` | filter tags by substring |
88
116
 
89
- Exit codes: `0` success (and for `--help`/`--version`), `4` on a `404` from the API, `1` for any other error (incl. a CKAN `success:false`) and for commander usage/parse errors.
117
+ ### `action` flag
90
118
 
91
- ---
119
+ | Flag | Meaning |
120
+ | --- | --- |
121
+ | `--param <key=value>` | query parameter (repeatable; duplicate keys are rejected) |
92
122
 
93
- ## Library usage
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
- ```ts
96
- import { GovDataClient, GovDataError } from "@maschinenlesbar.org/govdata-cli";
129
+ The **[Glossary](GLOSSARY.md)** decodes every CKAN term and search-parameter
130
+ name.
97
131
 
98
- const client = new GovDataClient(); // defaults to https://ckan.govdata.de
132
+ ## Common tasks
99
133
 
100
- const hits = await client.packageSearch({ q: "Haushalt", rows: 5 });
101
- const dataset = await client.packageShow(hits.results[0]!.id as string);
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
- // Generic escape hatch for any read action:
105
- const tags = await client.action<string[]>("tag_list", { query: "energie" });
137
+ ```bash
138
+ # Newest datasets first
139
+ govdata search Klima --rows 10 --sort "metadata_modified desc"
106
140
 
107
- try {
108
- await client.packageShow("does-not-exist");
109
- } catch (err) {
110
- if (err instanceof GovDataError) console.error(err.message);
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
- ### Client options
115
-
116
- ```ts
117
- new GovDataClient({
118
- baseUrl: "https://ckan.govdata.de",
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
- ### Methods
161
+ ## Output & scripting
128
162
 
129
- `packageSearch`, `packageShow`, `packageList`, `organizationList`, `organizationShow`,
130
- `groupList`, `groupShow`, `tagList`, `resourceShow`, and the generic `action(name, params)`.
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
- ## Architecture
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
- src/
138
- client/
139
- types.ts # CkanEnvelope, PackageSearchResult + parameter objects
140
- query.ts # dependency-free query-string builder
141
- http.ts # the Transport interface + default node:http/https transport
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
- **Design notes**
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
- - The HTTP layer is a single `Transport` function (`(req) => Promise<HttpResponse>`). The default
157
- uses `node:http`/`node:https`; tests inject a mock. This keeps the client free of any HTTP framework.
158
- - The client unwraps CKAN's `{ help, success, result }` envelope and raises `GovDataError`
159
- when `success` is false, so callers work directly with `result`.
160
- - A generic `action(name, params)` exposes every read action even where there is no typed convenience method. The action name is validated against `^[a-z0-9_]+$` and URL-encoded, so it cannot inject extra path segments, query string, or fragments into the request URL.
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
- ## Testing
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
- ```bash
168
- npm test # builds, then runs `node --test` over dist/test
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
- - **`query.test.ts`**query-string serialisation.
172
- - **`http.test.ts`**the default transport against a real loopback `http.createServer`.
173
- - **`engine.test.ts`** — URL building, JSON decoding, error mapping, 429/503 retry, redirects — mocked transport.
174
- - **`client.test.ts`**action URL/param mapping, result unwrapping, success:false handling — mocked transport.
175
- - **`cli.test.ts`** — end-to-end command parsing, `--param`/`--fq` handling and exit codes — mocked client.
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
- ## Continuous integration
235
+ ## Data license
178
236
 
179
- GitHub Actions workflows under `.github/workflows/`:
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
- - **ci.yml** — type-check, build and test on Node 20/22/24 for every push and PR.
182
- - **release.yml** — on a `v*` tag: verify the tag matches `package.json`, test, `npm pack`, and create a GitHub Release with the tarball.
183
- - **publish.yml** manual dispatch: publish to npm via OIDC **Trusted Publishing** (no stored `NPM_TOKEN`) with provenance.
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
 
@@ -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;AAC1C,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,yBAAyB,CAAC;SACrE,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"}
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"}
@@ -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"}
@@ -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":"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"}
@@ -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;AAOD,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;IAYvC,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;CAiCnB"}
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":"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"}
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,SAwE5B,CAAC"}
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"}
@@ -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
- reject(new GovDataNetworkError(`Response exceeded maxResponseBytes (${maxBytes})`));
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
- resolve({
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
- reject(new GovDataNetworkError(`Response stream error: ${err.message}`, { cause: err }));
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
- reject(err instanceof GovDataNetworkError ? err : new GovDataNetworkError(err.message, { cause: err }));
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":"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"}
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/client/http.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maschinenlesbar.org/govdata-cli",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "TypeScript API client and CLI for the open GovData CKAN catalogue API (ckan.govdata.de)",
5
5
  "type": "module",
6
6
  "bin": {