@tronsfey/openapi2cli 1.0.10 → 1.0.12
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 +160 -15
- package/README.zh.md +157 -16
- package/dist/cache.d.ts +23 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +98 -0
- package/dist/cache.js.map +1 -0
- package/dist/completer.d.ts +11 -0
- package/dist/completer.d.ts.map +1 -0
- package/dist/completer.js +223 -0
- package/dist/completer.js.map +1 -0
- package/dist/index.js +100 -13
- package/dist/index.js.map +1 -1
- package/dist/runner/http-client.d.ts +27 -0
- package/dist/runner/http-client.d.ts.map +1 -0
- package/dist/runner/http-client.js +199 -0
- package/dist/runner/http-client.js.map +1 -0
- package/dist/runner/output.d.ts +2 -0
- package/dist/runner/output.d.ts.map +1 -0
- package/dist/runner/output.js +40 -0
- package/dist/runner/output.js.map +1 -0
- package/dist/runner/proxy-runner.d.ts +15 -0
- package/dist/runner/proxy-runner.d.ts.map +1 -0
- package/dist/runner/proxy-runner.js +308 -0
- package/dist/runner/proxy-runner.js.map +1 -0
- package/package.json +12 -5
package/README.md
CHANGED
|
@@ -2,36 +2,107 @@ English | [中文](./README.zh.md)
|
|
|
2
2
|
|
|
3
3
|
# openapi2cli
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Two modes in one tool:
|
|
6
|
+
|
|
7
|
+
1. **Generate** — scaffold a fully typed Commander.js CLI project from an OpenAPI 3.x spec
|
|
8
|
+
2. **Run** — proxy an OpenAPI spec directly from the command line, no code generation needed
|
|
9
|
+
|
|
10
|
+
## Architecture
|
|
11
|
+
|
|
12
|
+
```mermaid
|
|
13
|
+
flowchart TD
|
|
14
|
+
CLI["CLI Entry · src/index.ts"]
|
|
15
|
+
|
|
16
|
+
CLI -->|"generate"| GEN["generate action"]
|
|
17
|
+
CLI -->|"run"| RUN["run action"]
|
|
18
|
+
CLI -->|"completion"| CMP["completer.ts\nbash / zsh / fish"]
|
|
19
|
+
CLI -->|"__completions"| HID["hidden: dynamic\ngroup & op listing"]
|
|
20
|
+
|
|
21
|
+
GEN --> PARSE["parseOASWithCache()\nsrc/cache.ts"]
|
|
22
|
+
GEN --> ANA["analyzeSchema()\nanalyzer/schema-analyzer.ts"]
|
|
23
|
+
GEN --> GENP["generateProject()\ngenerator/command-generator.ts"]
|
|
24
|
+
GENP --> TMPL["renderTemplate()\ngenerator/template-engine.ts\n+ Handlebars *.hbs"]
|
|
25
|
+
|
|
26
|
+
RUN --> CACHE["parseOASWithCache()\nsrc/cache.ts"]
|
|
27
|
+
RUN --> ANA2["analyzeSchema()"]
|
|
28
|
+
RUN --> PR["proxyRun()\nrunner/proxy-runner.ts"]
|
|
29
|
+
|
|
30
|
+
PR -->|"no op"| LIST["listOperations()"]
|
|
31
|
+
PR -->|"with op"| BOP["buildOperationsProgram()"]
|
|
32
|
+
BOP --> REG["registerOperation()"]
|
|
33
|
+
REG --> EXE["executeOperation()"]
|
|
34
|
+
EXE --> HC["createRuntimeClient()\nrunner/http-client.ts"]
|
|
35
|
+
HC -->|"REST"| AX["axios\n+ timeout + retry\n+ keep-alive"]
|
|
36
|
+
HC -->|"SSE"| SSE["fetch()\n+ AbortController"]
|
|
37
|
+
EXE --> FMT["formatOutput()\nrunner/output.ts"]
|
|
38
|
+
FMT --> OUT["JSON / YAML / Table\n+ JMESPath filter"]
|
|
39
|
+
|
|
40
|
+
CACHE --> DISK["~/.cache/openapi2cli/\nSHA-256 keyed, 1 h TTL"]
|
|
41
|
+
CACHE --> PARSE2["parseOAS()\nparser/oas-parser.ts"]
|
|
42
|
+
PARSE2 --> SP["swagger-parser\n$ref resolution + validation"]
|
|
43
|
+
|
|
44
|
+
ANA --> AUTH["extractAuthConfig()\nauth/auth-provider.ts"]
|
|
45
|
+
HID --> CACHE
|
|
46
|
+
HID --> ANA2
|
|
47
|
+
```
|
|
6
48
|
|
|
7
49
|
## Features
|
|
8
50
|
|
|
9
51
|
- Parse OAS 3.x specs from a **file path or URL** (full `$ref` resolution)
|
|
10
52
|
- Group operations by **tag** → Commander subcommand groups; untagged operations become top-level commands
|
|
11
53
|
- Generate **TypeScript source** with correct types, required/optional flags, enum `.choices()` validation
|
|
12
|
-
- **5 auth schemes** auto-detected from OAS security definitions
|
|
13
|
-
- **SSE streaming** via `eventsource-parser`
|
|
54
|
+
- **5 auth schemes** auto-detected from OAS security definitions (generate mode) or via CLI flags (run mode)
|
|
55
|
+
- **SSE streaming** via `eventsource-parser` — full SSE spec support, `[DONE]` sentinel handling
|
|
14
56
|
- **Pagination** via `--all-pages` (follows `Link: rel="next"` response headers)
|
|
15
57
|
- **JMESPath filtering** via `--query` on every command
|
|
16
58
|
- **CJK command names** — Chinese/Japanese/Korean operationIds auto-converted to pinyin
|
|
17
59
|
- **OpenAPI extensions**: `x-cli-name`, `x-cli-aliases`, `x-cli-ignore`, `x-cli-token-url`
|
|
18
60
|
- Generates **bilingual docs**: `README.md` (English) + `README.zh.md` (Chinese) + `SKILL.md` (Claude Code skill descriptor)
|
|
19
|
-
- Global `--endpoint`, `--format` (json/yaml/table), and `--verbose` on every generated CLI
|
|
20
61
|
|
|
21
62
|
## Installation
|
|
22
63
|
|
|
23
64
|
```bash
|
|
24
|
-
npm install -g openapi2cli
|
|
65
|
+
npm install -g @tronsfey/openapi2cli
|
|
25
66
|
```
|
|
26
67
|
|
|
27
68
|
## Usage
|
|
28
69
|
|
|
70
|
+
### Run mode (proxy — no code generation)
|
|
71
|
+
|
|
72
|
+
Call any OpenAPI endpoint directly. Auth is passed as CLI flags:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# List available operations
|
|
76
|
+
openapi2cli run --oas ./openapi.yaml
|
|
77
|
+
|
|
78
|
+
# Bearer token
|
|
79
|
+
openapi2cli run --oas ./openapi.yaml --bearer ghp_xxx repos get-repo --owner octocat --repo Hello-World
|
|
80
|
+
|
|
81
|
+
# API key
|
|
82
|
+
openapi2cli run --oas ./openapi.yaml --api-key sk-xxx --api-key-header X-Api-Key pets list-pets
|
|
83
|
+
|
|
84
|
+
# HTTP Basic
|
|
85
|
+
openapi2cli run --oas ./openapi.yaml --basic user:pass users get-user --username alice
|
|
86
|
+
|
|
87
|
+
# Extra headers
|
|
88
|
+
openapi2cli run --oas ./openapi.yaml --header "X-Request-Id: abc123" --header "X-Tenant: acme" ...
|
|
89
|
+
|
|
90
|
+
# Override base URL
|
|
91
|
+
openapi2cli run --oas ./openapi.yaml --endpoint https://staging.example.com --bearer xxx ...
|
|
92
|
+
|
|
93
|
+
# Output options (per operation)
|
|
94
|
+
openapi2cli run --oas ./openapi.yaml repos list-repo-issues --owner octocat --repo Hello-World \
|
|
95
|
+
--format table --query '[].title' --all-pages
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Generate mode (scaffold a typed CLI project)
|
|
99
|
+
|
|
29
100
|
```bash
|
|
30
101
|
# From a local file
|
|
31
|
-
openapi2cli --oas ./openapi.yaml --name my-api --output ./my-api-cli
|
|
102
|
+
openapi2cli generate --oas ./openapi.yaml --name my-api --output ./my-api-cli
|
|
32
103
|
|
|
33
104
|
# From a URL
|
|
34
|
-
openapi2cli --oas https://petstore3.swagger.io/api/v3/openapi.json --name petstore --output ./petstore-cli
|
|
105
|
+
openapi2cli generate --oas https://petstore3.swagger.io/api/v3/openapi.json --name petstore --output ./petstore-cli
|
|
35
106
|
```
|
|
36
107
|
|
|
37
108
|
Build and link the generated project:
|
|
@@ -155,19 +226,93 @@ my-api completions create --model gpt-4o --stream
|
|
|
155
226
|
|
|
156
227
|
The generated client uses `eventsource-parser` with the native `fetch` API. It supports multi-line `data:` payloads, named `event:` types, and silently drops `[DONE]` sentinels used by OpenAI-compatible APIs.
|
|
157
228
|
|
|
158
|
-
##
|
|
229
|
+
## Shell Completion
|
|
230
|
+
|
|
231
|
+
Enable tab-completion in your shell by sourcing the generated script once:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
# Bash — add to ~/.bashrc
|
|
235
|
+
eval "$(openapi2cli completion bash)"
|
|
236
|
+
|
|
237
|
+
# Zsh — add to ~/.zshrc
|
|
238
|
+
eval "$(openapi2cli completion zsh)"
|
|
159
239
|
|
|
240
|
+
# Fish
|
|
241
|
+
openapi2cli completion fish > ~/.config/fish/completions/openapi2cli.fish
|
|
160
242
|
```
|
|
161
|
-
openapi2cli [options]
|
|
162
243
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
244
|
+
Completion covers:
|
|
245
|
+
- Top-level commands (`generate`, `run`, `completion`)
|
|
246
|
+
- All flags for `generate` and `run`
|
|
247
|
+
- **Dynamic operation names** — after `run --oas <spec>` the completion script
|
|
248
|
+
calls `openapi2cli __completions` to look up group and operation names from
|
|
249
|
+
the spec at completion time
|
|
250
|
+
|
|
251
|
+
## CLI Reference
|
|
252
|
+
|
|
253
|
+
```
|
|
254
|
+
openapi2cli generate [options]
|
|
255
|
+
|
|
256
|
+
--oas <path|url> Path or URL to the OpenAPI 3.x spec (required)
|
|
257
|
+
--name <name> CLI executable name (required)
|
|
258
|
+
--output <dir> Output directory (required)
|
|
259
|
+
--overwrite Overwrite existing output directory
|
|
260
|
+
--no-cache Bypass spec cache (always re-fetch remote specs)
|
|
261
|
+
--cache-ttl <seconds> Cache TTL in seconds (default: 3600)
|
|
262
|
+
-h, --help Display help
|
|
263
|
+
|
|
264
|
+
openapi2cli run [options] [group] [operation] [operation-options]
|
|
265
|
+
|
|
266
|
+
--oas <path|url> OpenAPI 3.x spec (required)
|
|
267
|
+
--bearer <token> Authorization: Bearer <token>
|
|
268
|
+
--api-key <key> API key value
|
|
269
|
+
--api-key-header <header> Header name for the API key (default: X-Api-Key)
|
|
270
|
+
--basic <user:pass> HTTP Basic credentials
|
|
271
|
+
--header <Name: Value> Extra header, repeatable
|
|
272
|
+
--endpoint <url> Override base URL from the spec
|
|
273
|
+
--timeout <ms> Request timeout in milliseconds (default: 30000)
|
|
274
|
+
--retries <n> Max retry attempts for 5xx/network errors (default: 3)
|
|
275
|
+
--no-cache Bypass spec cache (always re-fetch remote specs)
|
|
276
|
+
--cache-ttl <seconds> Cache TTL in seconds (default: 3600)
|
|
277
|
+
-h, --help Display help
|
|
278
|
+
|
|
279
|
+
Per-operation output flags (after the operation name):
|
|
280
|
+
--format json|yaml|table Output format (default: json)
|
|
281
|
+
--query <jmespath> Filter response with a JMESPath expression
|
|
282
|
+
--all-pages Auto-paginate via Link rel="next" headers
|
|
283
|
+
--verbose Print HTTP method + URL to stderr
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
### Spec Caching
|
|
287
|
+
|
|
288
|
+
Remote OAS specs are cached in `~/.cache/openapi2cli/` with a 1-hour TTL by default,
|
|
289
|
+
making repeated `run` invocations near-instant after the first load.
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
# Force a fresh fetch (bypass cache)
|
|
293
|
+
openapi2cli run --oas https://api.example.com/openapi.json --no-cache ...
|
|
294
|
+
|
|
295
|
+
# Extend cache TTL to 24 hours
|
|
296
|
+
openapi2cli run --oas https://api.example.com/openapi.json --cache-ttl 86400 ...
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Stability Flags
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
# Set a 60-second timeout for slow APIs
|
|
303
|
+
openapi2cli run --oas ./spec.yaml --timeout 60000 items list-items
|
|
304
|
+
|
|
305
|
+
# Disable retries (fail immediately on errors)
|
|
306
|
+
openapi2cli run --oas ./spec.yaml --retries 0 items list-items
|
|
307
|
+
|
|
308
|
+
# Aggressive retry for flaky staging environments
|
|
309
|
+
openapi2cli run --oas ./spec.yaml --retries 5 items list-items
|
|
169
310
|
```
|
|
170
311
|
|
|
312
|
+
Retries use exponential backoff (500 ms → 1 s → 2 s) and only apply to retryable
|
|
313
|
+
errors: network failures (`ECONNREFUSED`, `ETIMEDOUT`, `ECONNRESET`) and HTTP 429, 500,
|
|
314
|
+
502, 503, 504. Non-retryable 4xx errors (401, 403, 404, 422 …) fail immediately.
|
|
315
|
+
|
|
171
316
|
## License
|
|
172
317
|
|
|
173
318
|
MIT
|
package/README.zh.md
CHANGED
|
@@ -2,36 +2,107 @@
|
|
|
2
2
|
|
|
3
3
|
# openapi2cli
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
两种模式,一个工具:
|
|
6
|
+
|
|
7
|
+
1. **generate(生成)** — 将 OpenAPI 3.x 规范脚手架为完整的 TypeScript CLI 项目
|
|
8
|
+
2. **run(直接代理)** — 无需生成代码,直接在命令行调用 OpenAPI 接口
|
|
9
|
+
|
|
10
|
+
## 架构图
|
|
11
|
+
|
|
12
|
+
```mermaid
|
|
13
|
+
flowchart TD
|
|
14
|
+
CLI["CLI 入口 · src/index.ts"]
|
|
15
|
+
|
|
16
|
+
CLI -->|"generate"| GEN["generate 动作"]
|
|
17
|
+
CLI -->|"run"| RUN["run 动作"]
|
|
18
|
+
CLI -->|"completion"| CMP["completer.ts\nbash / zsh / fish"]
|
|
19
|
+
CLI -->|"__completions"| HID["隐藏命令:动态\n获取命令组和操作名"]
|
|
20
|
+
|
|
21
|
+
GEN --> PARSE["parseOASWithCache()\nsrc/cache.ts"]
|
|
22
|
+
GEN --> ANA["analyzeSchema()\nanalyzer/schema-analyzer.ts"]
|
|
23
|
+
GEN --> GENP["generateProject()\ngenerator/command-generator.ts"]
|
|
24
|
+
GENP --> TMPL["renderTemplate()\ngenerator/template-engine.ts\n+ Handlebars *.hbs"]
|
|
25
|
+
|
|
26
|
+
RUN --> CACHE["parseOASWithCache()\nsrc/cache.ts"]
|
|
27
|
+
RUN --> ANA2["analyzeSchema()"]
|
|
28
|
+
RUN --> PR["proxyRun()\nrunner/proxy-runner.ts"]
|
|
29
|
+
|
|
30
|
+
PR -->|"无操作名"| LIST["listOperations()"]
|
|
31
|
+
PR -->|"有操作名"| BOP["buildOperationsProgram()"]
|
|
32
|
+
BOP --> REG["registerOperation()"]
|
|
33
|
+
REG --> EXE["executeOperation()"]
|
|
34
|
+
EXE --> HC["createRuntimeClient()\nrunner/http-client.ts"]
|
|
35
|
+
HC -->|"REST"| AX["axios\n+ 超时 + 重试\n+ keep-alive"]
|
|
36
|
+
HC -->|"SSE"| SSE["fetch()\n+ AbortController"]
|
|
37
|
+
EXE --> FMT["formatOutput()\nrunner/output.ts"]
|
|
38
|
+
FMT --> OUT["JSON / YAML / 表格\n+ JMESPath 过滤"]
|
|
39
|
+
|
|
40
|
+
CACHE --> DISK["~/.cache/openapi2cli/\nSHA-256 键,1 小时 TTL"]
|
|
41
|
+
CACHE --> PARSE2["parseOAS()\nparser/oas-parser.ts"]
|
|
42
|
+
PARSE2 --> SP["swagger-parser\n$ref 解析 + 校验"]
|
|
43
|
+
|
|
44
|
+
ANA --> AUTH["extractAuthConfig()\nauth/auth-provider.ts"]
|
|
45
|
+
HID --> CACHE
|
|
46
|
+
HID --> ANA2
|
|
47
|
+
```
|
|
6
48
|
|
|
7
49
|
## 功能特性
|
|
8
50
|
|
|
9
51
|
- 支持从**文件路径或 URL** 解析 OAS 3.x 规范(完整 `$ref` 解析)
|
|
10
52
|
- 按 **tag** 分组操作,生成 Commander 子命令组;未分组的操作注册为顶层命令
|
|
11
53
|
- 生成带完整类型标注的 **TypeScript 源码**,支持必填/可选参数、枚举 `.choices()` 校验
|
|
12
|
-
- **5
|
|
13
|
-
- **SSE 流式输出**基于 `eventsource-parser
|
|
54
|
+
- **5 种认证方案**:生成模式从 OAS 安全定义自动检测;run 模式通过命令行参数传入
|
|
55
|
+
- **SSE 流式输出**基于 `eventsource-parser`,支持 `[DONE]` 哨兵处理
|
|
14
56
|
- **自动分页**:`--all-pages` 参数,自动跟随 `Link: rel="next"` 响应头翻页
|
|
15
57
|
- **JMESPath 过滤**:每条命令均支持 `--query` 参数
|
|
16
58
|
- **中文命令名支持**:中/日/韩 operationId 自动转换为拼音
|
|
17
59
|
- **OpenAPI 扩展**:`x-cli-name`、`x-cli-aliases`、`x-cli-ignore`、`x-cli-token-url`
|
|
18
|
-
- 自动生成**双语文档**:`README.md`(英文)+ `README.zh.md`(中文)+ `SKILL.md
|
|
19
|
-
- 所有生成的 CLI 均内置全局选项:`--endpoint`、`--format`(json/yaml/table)、`--verbose`
|
|
60
|
+
- 自动生成**双语文档**:`README.md`(英文)+ `README.zh.md`(中文)+ `SKILL.md`
|
|
20
61
|
|
|
21
62
|
## 安装
|
|
22
63
|
|
|
23
64
|
```bash
|
|
24
|
-
npm install -g openapi2cli
|
|
65
|
+
npm install -g @tronsfey/openapi2cli
|
|
25
66
|
```
|
|
26
67
|
|
|
27
68
|
## 使用方法
|
|
28
69
|
|
|
70
|
+
### run 模式(直接代理,无需生成代码)
|
|
71
|
+
|
|
72
|
+
授权信息通过命令行参数传入:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# 列出所有可用操作
|
|
76
|
+
openapi2cli run --oas ./openapi.yaml
|
|
77
|
+
|
|
78
|
+
# Bearer Token
|
|
79
|
+
openapi2cli run --oas ./openapi.yaml --bearer ghp_xxx repos get-repo --owner octocat --repo Hello-World
|
|
80
|
+
|
|
81
|
+
# API Key
|
|
82
|
+
openapi2cli run --oas ./openapi.yaml --api-key sk-xxx --api-key-header X-Api-Key pets list-pets
|
|
83
|
+
|
|
84
|
+
# HTTP Basic
|
|
85
|
+
openapi2cli run --oas ./openapi.yaml --basic user:pass users get-user --username alice
|
|
86
|
+
|
|
87
|
+
# 自定义请求头(可多次指定)
|
|
88
|
+
openapi2cli run --oas ./openapi.yaml --header "X-Request-Id: abc123" --header "X-Tenant: acme" ...
|
|
89
|
+
|
|
90
|
+
# 覆盖 Base URL
|
|
91
|
+
openapi2cli run --oas ./openapi.yaml --endpoint https://staging.example.com --bearer xxx ...
|
|
92
|
+
|
|
93
|
+
# 输出选项(在操作名称之后指定)
|
|
94
|
+
openapi2cli run --oas ./openapi.yaml repos list-repo-issues --owner octocat --repo Hello-World \
|
|
95
|
+
--format table --query '[].title' --all-pages
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### generate 模式(生成完整 CLI 项目)
|
|
99
|
+
|
|
29
100
|
```bash
|
|
30
101
|
# 从本地文件生成
|
|
31
|
-
openapi2cli --oas ./openapi.yaml --name my-api --output ./my-api-cli
|
|
102
|
+
openapi2cli generate --oas ./openapi.yaml --name my-api --output ./my-api-cli
|
|
32
103
|
|
|
33
104
|
# 从 URL 生成
|
|
34
|
-
openapi2cli --oas https://petstore3.swagger.io/api/v3/openapi.json --name petstore --output ./petstore-cli
|
|
105
|
+
openapi2cli generate --oas https://petstore3.swagger.io/api/v3/openapi.json --name petstore --output ./petstore-cli
|
|
35
106
|
```
|
|
36
107
|
|
|
37
108
|
构建并链接生成的项目:
|
|
@@ -155,19 +226,89 @@ my-api completions create --model gpt-4o --stream
|
|
|
155
226
|
|
|
156
227
|
生成的客户端使用 `eventsource-parser`,支持多行 `data:` 载荷、命名 `event:` 类型,并静默丢弃 OpenAI 兼容 API 常用的 `[DONE]` 哨兵。
|
|
157
228
|
|
|
158
|
-
##
|
|
229
|
+
## Shell 自动补全
|
|
230
|
+
|
|
231
|
+
在 shell 中一次性 source 生成的补全脚本,即可启用 Tab 补全:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
# Bash — 添加到 ~/.bashrc
|
|
235
|
+
eval "$(openapi2cli completion bash)"
|
|
236
|
+
|
|
237
|
+
# Zsh — 添加到 ~/.zshrc
|
|
238
|
+
eval "$(openapi2cli completion zsh)"
|
|
239
|
+
|
|
240
|
+
# Fish
|
|
241
|
+
openapi2cli completion fish > ~/.config/fish/completions/openapi2cli.fish
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
支持补全:
|
|
245
|
+
- 顶层命令(`generate`、`run`、`completion`)
|
|
246
|
+
- `generate` 和 `run` 的所有参数
|
|
247
|
+
- **动态操作名称** — 在 `run --oas <spec>` 之后,补全脚本会调用
|
|
248
|
+
`openapi2cli __completions` 从规范中实时查找命令组和操作名称
|
|
249
|
+
|
|
250
|
+
## 命令行参考
|
|
251
|
+
|
|
252
|
+
```
|
|
253
|
+
openapi2cli generate [options]
|
|
254
|
+
|
|
255
|
+
--oas <path|url> OpenAPI 3.x 规范的文件路径或 URL(必填)
|
|
256
|
+
--name <name> CLI 可执行文件名称(必填)
|
|
257
|
+
--output <dir> 输出目录(必填)
|
|
258
|
+
--overwrite 覆盖已存在的输出目录
|
|
259
|
+
--no-cache 跳过规范缓存(始终重新拉取远端规范)
|
|
260
|
+
--cache-ttl <seconds> 缓存 TTL(秒),默认 3600
|
|
261
|
+
-h, --help 显示帮助信息
|
|
262
|
+
|
|
263
|
+
openapi2cli run [options] [group] [operation] [operation-options]
|
|
264
|
+
|
|
265
|
+
--oas <path|url> OpenAPI 3.x 规范(必填)
|
|
266
|
+
--bearer <token> Authorization: Bearer <token>
|
|
267
|
+
--api-key <key> API Key 值
|
|
268
|
+
--api-key-header <header> API Key 的请求头名称(默认:X-Api-Key)
|
|
269
|
+
--basic <user:pass> HTTP Basic 凭证
|
|
270
|
+
--header <Name: Value> 自定义请求头,可多次指定
|
|
271
|
+
--endpoint <url> 覆盖规范中的 Base URL
|
|
272
|
+
--timeout <ms> 请求超时(毫秒),默认 30000
|
|
273
|
+
--retries <n> 5xx/网络错误的最大重试次数,默认 3
|
|
274
|
+
--no-cache 跳过规范缓存(始终重新拉取远端规范)
|
|
275
|
+
--cache-ttl <seconds> 缓存 TTL(秒),默认 3600
|
|
276
|
+
-h, --help 显示帮助信息
|
|
277
|
+
|
|
278
|
+
操作级输出选项(在操作名称之后指定):
|
|
279
|
+
--format json|yaml|table 输出格式(默认:json)
|
|
280
|
+
--query <jmespath> JMESPath 表达式,过滤响应
|
|
281
|
+
--all-pages 自动翻页(跟随 Link rel="next" 响应头)
|
|
282
|
+
--verbose 向 stderr 打印 HTTP 方法和 URL
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### 规范缓存
|
|
286
|
+
|
|
287
|
+
远端 OAS 规范默认缓存到 `~/.cache/openapi2cli/`,TTL 1 小时。
|
|
288
|
+
首次加载后,后续调用几乎无延迟。
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
# 强制重新拉取(跳过缓存)
|
|
292
|
+
openapi2cli run --oas https://api.example.com/openapi.json --no-cache ...
|
|
159
293
|
|
|
294
|
+
# 延长缓存到 24 小时
|
|
295
|
+
openapi2cli run --oas https://api.example.com/openapi.json --cache-ttl 86400 ...
|
|
160
296
|
```
|
|
161
|
-
openapi2cli [options]
|
|
162
297
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
298
|
+
### 稳定性选项
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
# 为慢速 API 设置 60 秒超时
|
|
302
|
+
openapi2cli run --oas ./spec.yaml --timeout 60000 items list-items
|
|
303
|
+
|
|
304
|
+
# 禁用重试(出错立即失败)
|
|
305
|
+
openapi2cli run --oas ./spec.yaml --retries 0 items list-items
|
|
169
306
|
```
|
|
170
307
|
|
|
308
|
+
重试使用指数退避(500 ms → 1 s → 2 s),仅对可重试错误生效:
|
|
309
|
+
网络故障(`ECONNREFUSED`、`ETIMEDOUT`、`ECONNRESET`)及 HTTP 429、500、502、503、504。
|
|
310
|
+
非可重试的 4xx 错误(401、403、404、422 等)立即失败。
|
|
311
|
+
|
|
171
312
|
## 许可证
|
|
172
313
|
|
|
173
314
|
MIT
|
package/dist/cache.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAS Spec Caching — src/cache.ts
|
|
3
|
+
*
|
|
4
|
+
* Wraps parseOAS() with a disk-based cache in ~/.cache/openapi2cli/.
|
|
5
|
+
* Only remote URLs are cached (local files are cheap to read directly).
|
|
6
|
+
* Cache keys are SHA-256 hashes of the input URL.
|
|
7
|
+
* TTL: configurable, default 3600 seconds (1 hour).
|
|
8
|
+
*/
|
|
9
|
+
import { OpenAPIV3 } from 'openapi-types';
|
|
10
|
+
/**
|
|
11
|
+
* Parse an OpenAPI spec with optional disk caching.
|
|
12
|
+
*
|
|
13
|
+
* - Local file paths: always calls parseOAS() directly (never cached).
|
|
14
|
+
* - Remote URLs: checks ~/.cache/openapi2cli/<sha256>.json first;
|
|
15
|
+
* re-fetches if the file is older than ttlMs or noCache is true.
|
|
16
|
+
*/
|
|
17
|
+
export declare function parseOASWithCache(input: string, opts?: {
|
|
18
|
+
noCache?: boolean;
|
|
19
|
+
ttlMs?: number;
|
|
20
|
+
}): Promise<OpenAPIV3.Document>;
|
|
21
|
+
/** Remove all cached specs (useful for `--no-cache` debug workflows). */
|
|
22
|
+
export declare function clearCache(): Promise<void>;
|
|
23
|
+
//# sourceMappingURL=cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAc1C;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,MAAM,EACb,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/C,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,CA4B7B;AAED,yEAAyE;AACzE,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAEhD"}
|
package/dist/cache.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OAS Spec Caching — src/cache.ts
|
|
4
|
+
*
|
|
5
|
+
* Wraps parseOAS() with a disk-based cache in ~/.cache/openapi2cli/.
|
|
6
|
+
* Only remote URLs are cached (local files are cheap to read directly).
|
|
7
|
+
* Cache keys are SHA-256 hashes of the input URL.
|
|
8
|
+
* TTL: configurable, default 3600 seconds (1 hour).
|
|
9
|
+
*/
|
|
10
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
13
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
14
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
15
|
+
}
|
|
16
|
+
Object.defineProperty(o, k2, desc);
|
|
17
|
+
}) : (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
o[k2] = m[k];
|
|
20
|
+
}));
|
|
21
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
22
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
23
|
+
}) : function(o, v) {
|
|
24
|
+
o["default"] = v;
|
|
25
|
+
});
|
|
26
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
27
|
+
var ownKeys = function(o) {
|
|
28
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
29
|
+
var ar = [];
|
|
30
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
31
|
+
return ar;
|
|
32
|
+
};
|
|
33
|
+
return ownKeys(o);
|
|
34
|
+
};
|
|
35
|
+
return function (mod) {
|
|
36
|
+
if (mod && mod.__esModule) return mod;
|
|
37
|
+
var result = {};
|
|
38
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
39
|
+
__setModuleDefault(result, mod);
|
|
40
|
+
return result;
|
|
41
|
+
};
|
|
42
|
+
})();
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.parseOASWithCache = parseOASWithCache;
|
|
45
|
+
exports.clearCache = clearCache;
|
|
46
|
+
const crypto = __importStar(require("crypto"));
|
|
47
|
+
const os = __importStar(require("os"));
|
|
48
|
+
const path = __importStar(require("path"));
|
|
49
|
+
const fse = __importStar(require("fs-extra"));
|
|
50
|
+
const oas_parser_1 = require("./parser/oas-parser");
|
|
51
|
+
const CACHE_DIR = path.join(os.homedir(), '.cache', 'openapi2cli');
|
|
52
|
+
const DEFAULT_TTL_MS = 3600000; // 1 hour
|
|
53
|
+
function cacheKey(input) {
|
|
54
|
+
return crypto.createHash('sha256').update(input).digest('hex');
|
|
55
|
+
}
|
|
56
|
+
function cacheFile(input) {
|
|
57
|
+
return path.join(CACHE_DIR, `${cacheKey(input)}.json`);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Parse an OpenAPI spec with optional disk caching.
|
|
61
|
+
*
|
|
62
|
+
* - Local file paths: always calls parseOAS() directly (never cached).
|
|
63
|
+
* - Remote URLs: checks ~/.cache/openapi2cli/<sha256>.json first;
|
|
64
|
+
* re-fetches if the file is older than ttlMs or noCache is true.
|
|
65
|
+
*/
|
|
66
|
+
async function parseOASWithCache(input, opts = {}) {
|
|
67
|
+
const isUrl = /^https?:\/\//.test(input);
|
|
68
|
+
// Local files: skip cache entirely
|
|
69
|
+
if (!isUrl)
|
|
70
|
+
return (0, oas_parser_1.parseOAS)(input);
|
|
71
|
+
const ttl = opts.ttlMs ?? DEFAULT_TTL_MS;
|
|
72
|
+
const file = cacheFile(input);
|
|
73
|
+
if (!opts.noCache) {
|
|
74
|
+
try {
|
|
75
|
+
const stat = await fse.stat(file);
|
|
76
|
+
if (Date.now() - stat.mtimeMs < ttl) {
|
|
77
|
+
return (await fse.readJSON(file));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// File does not exist or is unreadable — proceed to fetch
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const doc = await (0, oas_parser_1.parseOAS)(input);
|
|
85
|
+
try {
|
|
86
|
+
await fse.ensureDir(CACHE_DIR);
|
|
87
|
+
await fse.writeJSON(file, doc);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// Cache write failure is non-fatal — proceed with the parsed doc
|
|
91
|
+
}
|
|
92
|
+
return doc;
|
|
93
|
+
}
|
|
94
|
+
/** Remove all cached specs (useful for `--no-cache` debug workflows). */
|
|
95
|
+
async function clearCache() {
|
|
96
|
+
await fse.emptyDir(CACHE_DIR);
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BH,8CA+BC;AAGD,gCAEC;AA7DD,+CAAiC;AACjC,uCAAyB;AACzB,2CAA6B;AAC7B,8CAAgC;AAEhC,oDAA+C;AAE/C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,aAAa,CAAC,CAAC;AACnE,MAAM,cAAc,GAAG,OAAS,CAAC,CAAC,SAAS;AAE3C,SAAS,QAAQ,CAAC,KAAa;IAC7B,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC9B,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AACzD,CAAC;AAED;;;;;;GAMG;AACI,KAAK,UAAU,iBAAiB,CACrC,KAAa,EACb,OAA8C,EAAE;IAEhD,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAEzC,mCAAmC;IACnC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAA,qBAAQ,EAAC,KAAK,CAAC,CAAC;IAEnC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,IAAI,cAAc,CAAC;IACzC,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAE9B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAClB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,GAAG,GAAG,EAAE,CAAC;gBACpC,OAAO,CAAC,MAAM,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAuB,CAAC;YAC1D,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,0DAA0D;QAC5D,CAAC;IACH,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,IAAA,qBAAQ,EAAC,KAAK,CAAC,CAAC;IAClC,IAAI,CAAC;QACH,MAAM,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;QAC/B,MAAM,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,iEAAiE;IACnE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,yEAAyE;AAClE,KAAK,UAAU,UAAU;IAC9B,MAAM,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shell completion script generators for openapi2cli.
|
|
3
|
+
*
|
|
4
|
+
* Each function returns a string that can be sourced by the user's shell.
|
|
5
|
+
* Dynamic operation completion (after `run --oas <spec>`) is handled by
|
|
6
|
+
* calling back into the hidden `__completions` subcommand.
|
|
7
|
+
*/
|
|
8
|
+
export declare function generateBashCompletion(): string;
|
|
9
|
+
export declare function generateZshCompletion(): string;
|
|
10
|
+
export declare function generateFishCompletion(): string;
|
|
11
|
+
//# sourceMappingURL=completer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"completer.d.ts","sourceRoot":"","sources":["../src/completer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,wBAAgB,sBAAsB,IAAI,MAAM,CAyE/C;AAID,wBAAgB,qBAAqB,IAAI,MAAM,CAyF9C;AAID,wBAAgB,sBAAsB,IAAI,MAAM,CAsC/C"}
|