@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 CHANGED
@@ -2,36 +2,107 @@ English | [中文](./README.zh.md)
2
2
 
3
3
  # openapi2cli
4
4
 
5
- Generate a fully typed [Commander.js](https://github.com/tj/commander.js) CLI project from an OpenAPI 3.x specification — in one command.
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: Bearer, API Key, HTTP Basic, OAuth2 Client Credentials, custom dynamic token provider
13
- - **SSE streaming** via `eventsource-parser` (Node.js-native, used by Anthropic SDK) — full SSE spec support, `[DONE]` sentinel handling
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
- ## CLI Options
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
- Options:
164
- --oas <path|url> Path or URL to the OpenAPI 3.x spec (required)
165
- --name <name> CLI executable name (required)
166
- --output <dir> Output directory (required)
167
- --overwrite Overwrite existing output directory
168
- -h, --help Display help
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
- 一条命令,将 OpenAPI 3.x 规范生成为完整的 [Commander.js](https://github.com/tj/commander.js) TypeScript CLI 项目。
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 种认证方案**自动从 OAS 安全定义中检测:Bearer、API Key、HTTP Basic、OAuth2 Client Credentials、自定义动态 Token
13
- - **SSE 流式输出**基于 `eventsource-parser`,支持自动重连和 `[DONE]` 哨兵处理
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`(Claude Code 技能描述文件)
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
- --oas <path|url> OpenAPI 3.x 规范的文件路径或 URL(必填)
165
- --name <name> CLI 可执行文件名称(必填)
166
- --output <dir> 输出目录(必填)
167
- --overwrite 覆盖已存在的输出目录
168
- -h, --help 显示帮助信息
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
@@ -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"}