swagger-digest 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 swagger-digest contributors
3
+ Copyright (c) 2026 VladLegkowski
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
21
+ SOFTWARE.
package/README.md CHANGED
@@ -25,8 +25,53 @@ For a direct spec URL:
25
25
  npx swagger-digest --url https://example.com/openapi.yaml --out-dir ./docs
26
26
  ```
27
27
 
28
+ If the Swagger UI initializer lists several spec definitions (`urls: [{ url, name }, …]`), the tool probes them in the order they appear and uses the first one that parses, printing a notice to stderr naming the pick and the alternatives. To choose a specific spec yourself, pass it explicitly:
29
+
30
+ ```bash
31
+ npx swagger-digest --url https://api.example.com/swagger-ui \
32
+ --spec https://api.example.com/v2/tenant-a.json --out-dir ./docs
33
+ ```
34
+
35
+ `--spec` overrides all discovery: the given URL is fetched directly (with the same header scoping and size limits) and the Swagger UI page is never consulted when it parses successfully.
36
+
37
+ ### Writing to stdout
38
+
39
+ ```bash
40
+ npx swagger-digest --url https://petstore.swagger.io/ --stdout > petstore.md
41
+ npx swagger-digest --url https://api.example.com/openapi.json --stdout | pbcopy
42
+ ```
43
+
44
+ `--stdout` prints the digest to standard output instead of saving a file — handy for piping into other tools or copying to the clipboard. Progress and warnings go to stderr, so the pipe receives only the Markdown. `--stdout` cannot be combined with `--out-dir` or `--filename`; the CLI exits with a clear error if you try.
45
+
28
46
  Run `npx swagger-digest --help` for all CLI options. The package requires Node.js 20 or newer.
29
47
 
48
+ ### Filtering and token budget
49
+
50
+ Large specs produce large digests. The CLI can remove whole operations before rendering and/or trim the remaining digest to an approximate token budget:
51
+
52
+ ```bash
53
+ # Keep only operations tagged "Payments", plus everything under /invoices
54
+ npx swagger-digest --url https://api.example.com/openapi.json \
55
+ --include-tag Payments --path-prefix /payments/ --out-dir ./docs
56
+
57
+ # Drop a noisy tag
58
+ npx swagger-digest --url https://api.example.com/openapi.json --exclude-tag Internal
59
+
60
+ # Fit the digest into a model's context window
61
+ npx swagger-digest --url https://api.example.com/openapi.json --max-tokens 50000
62
+ ```
63
+
64
+ How `--max-tokens` trims (in this fixed order, re-checked against the estimate after each step):
65
+
66
+ 1. Drop declared example payloads (synthetic examples are never emitted).
67
+ 2. Shorten long descriptions.
68
+ 3. Collapse parameter/response detail per tag — the **tag priority rule** is that the tag appearing **last in the document** is collapsed first (lowest priority), one tag per step.
69
+ 4. Keep only the Quick index entries (no endpoint detail, no data types).
70
+
71
+ A `## Trimmed` note at the end of the digest records exactly which steps were applied. After every step, schemas that became unreachable (referenced only by collapsed/removed operations) are dropped from the Data types section. The token estimator is a heuristic, **not** a real tokenizer — treat `--max-tokens` as a guide, not a guarantee. Unknown tag names passed to `--include-tag`/`--exclude-tag` produce a warning on stderr listing the tags that exist in the spec.
72
+
73
+ The same options are available programmatically via the third argument of `transformOpenApiToMarkdown(spec, sourceUrl, { includeTags, excludeTags, pathPrefix, maxTokens, onWarning })`.
74
+
30
75
  ## What it extracts
31
76
 
32
77
  The retrieval strategy deliberately avoids scraping rendered operation accordions or simulating UI clicks:
@@ -45,6 +90,37 @@ npx playwright install chromium
45
90
 
46
91
  Then run the CLI again. Use `--no-browser` to disable the fallback.
47
92
 
93
+ ### Authentication headers
94
+
95
+ Some Swagger UI pages and spec URLs live behind authentication. Pass custom headers with `-H`/`--header` (repeatable) or `--cookie`:
96
+
97
+ ```bash
98
+ npx swagger-digest \
99
+ --url https://api.example.com/swagger-ui \
100
+ --header "Authorization: Bearer eyJhbGciOi..." \
101
+ --out-dir ./docs
102
+ ```
103
+
104
+ Or with a session cookie:
105
+
106
+ ```bash
107
+ npx swagger-digest --url https://api.example.com/swagger-ui --cookie "session=abc123"
108
+ ```
109
+
110
+ You can also supply headers through the `SWAGGER_DIGEST_HEADER` environment variable, with one `Name: value` pair per line. `-H` flags override environment entries on conflicting header names:
111
+
112
+ ```bash
113
+ export SWAGGER_DIGEST_HEADER=$'Authorization: Bearer eyJ…\nX-Tenant: acme'
114
+ npx swagger-digest --url https://api.example.com/swagger-ui
115
+ ```
116
+
117
+ **Scoping and safety:**
118
+
119
+ - Custom headers are sent **only** to the origin of the URL you supply. If the discovered spec, a redirect, or a Swagger UI script lives on a different origin, that request is made without your headers and a warning naming the other origin is printed to stderr.
120
+ - In the headless-browser fallback, headers are injected per-request (only for your origin) — they never reach CDNs or third-party scripts loaded by the page.
121
+ - Header values are never logged, written to the digest, or included in error messages.
122
+ - ⚠️ **Shell history:** secrets passed with `-H` can end up in your shell history file (`~/.bash_history`, `~/.zsh_history`). Prefer the `SWAGGER_DIGEST_HEADER` environment variable, or prefix the command with a space if your shell is configured to ignore leading-space entries.
123
+
48
124
  ### Troubleshooting access through a VPN
49
125
 
50
126
  The ordinary HTTP fetches use Node.js networking; they do not automatically reuse a browser's VPN extension, cookies, or signed-in session. If the Swagger page works in Chrome but not in the CLI, first test the same URL from the terminal:
@@ -55,6 +131,14 @@ curl -v -L 'https://your-host.example/path/to/swagger-ui' -o /tmp/swagger-page.h
55
131
 
56
132
  If `curl` cannot connect or receives `401`/`403`, connect a system-level VPN that also routes terminal applications, or configure the relevant corporate proxy/authentication for the terminal. Installing Playwright alone does not make a browser-only VPN extension available to its separate Chromium instance. If terminal access succeeds, the extractor now also reads same-origin Swagger UI initializer/config scripts and tries spec paths relative to the supplied page's context path.
57
133
 
134
+ ## Security notes
135
+
136
+ **What the tool fetches:** the URL you supply (a Swagger UI page or direct OpenAPI JSON/YAML URL), same-origin Swagger UI initializer/config scripts, the spec URL referenced by that page, and a short list of common spec paths on the same origin (`/v3/api-docs`, `/swagger.json`, …). The optional Playwright fallback loads the same page in a headless browser.
137
+
138
+ **What it does not forward:** cookies or Authorization headers are never sent automatically. Custom headers you pass with `--header`/`--cookie` (see below) are sent **only** to the origin of the URL you supplied. If the page redirects to another origin, or the discovered spec lives on a different origin, those requests are made without your headers and a warning naming the other origin is printed to stderr. Response bodies are capped (10 MB by default, configurable with `--max-bytes`), and redirects are followed at most 5 times.
139
+
140
+ **Embedding in a server:** if you call `fetchOpenApiSpec` from a server that accepts user-supplied URLs, enable `blockPrivateNetworks: true` in the fetch options. Without it, a caller can point the tool at `http://169.254.169.254/…` or other internal addresses from your infrastructure (SSRF). The check rejects loopback, link-local (including the cloud-metadata address 169.254.169.254), private, and unique-local addresses, and applies after redirects. Note the documented DNS-rebinding limitation in the code — for hostile multi-tenant input, use a dedicated egress proxy.
141
+
58
142
  ## Markdown format
59
143
 
60
144
  The generated document includes:
@@ -100,7 +184,7 @@ src/
100
184
  ## Limitations
101
185
 
102
186
  - The tool downloads specs exposed by the supplied server. It does not bypass authentication, browser access controls, or network restrictions.
103
- - External schema references are retained as named type references where possible; the tool does not currently fetch and bundle arbitrary external documents.
187
+ - External `$ref` documents are bundled best-effort: references to other HTTP(S) documents are fetched (one level deep, at most 5 documents) and their schemas inlined under namespaced names such as `meta_SharedMeta`. If an external document is unreachable or unparsable, the reference degrades to a named type reference and the digest still succeeds.
104
188
  - Declared request/response examples are preserved. When an example is absent but a schema exists, a representative JSON example is generated from that schema and clearly marked as illustrative rather than spec-authored. The transformer includes the primary success response and applicable common error responses to balance useful payload context against digest size.
105
189
  - A generated digest is a compact developer reference, not a replacement for the source OpenAPI contract.
106
190