ice-jade 0.1.0 → 0.5.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 550577afe0478429f7d36a2d3a3fc3c3d332f648bf42ba4047ebc2c8cc067c91
4
- data.tar.gz: 0a96c1e1cdeaab1cc213223313545a6353ad4c5301c2b4da6049480d3f75b6e8
3
+ metadata.gz: 68cefcd1f994be3fd223da84038c78ba39087227ac6ba22cfef06912b1e890d6
4
+ data.tar.gz: a5ee1b22d8929a592aa65a7725b94fdf2e2f63e071e202bd8e18ddf666410f59
5
5
  SHA512:
6
- metadata.gz: 542652be59f54b3f09e20d3cffa944a7a0303ec6b181e68ba614c5f3ee81f13310c855b6ac8dd5c75a7befdf963f20d89767841c7a660ca391c6fbc2df8c08a0
7
- data.tar.gz: 2995c0ee5c479e026c33d2c9d43192472d890c6b094c3007df4357c568660cc241081c6d4ac612de6837eb8b4bbac71f707d7e12a67e23626d3fabb31824baa6
6
+ metadata.gz: 2fff58382ca71e712f1a7a21c23bb4465dee51789efc318aeae013af265d43ee43a5fc36f48cb8fc009069b28aff5fed42b90086696210a3424d1bd86d27fe20
7
+ data.tar.gz: 51fbc0b9a38a4e77da420c0f9c7464282940c643b173bbd106cb51e49e1f51dfbbcf85bbb313cc4bfda195f0cebf4422908412f453d91e0f1b4124cfe24010eb
data/README.md CHANGED
@@ -1,6 +1,12 @@
1
1
  # ice-jade
2
2
 
3
- 管理多种 IM 接口的 Ruby SDK gem,仅内部用。外部接口见 ignister。
3
+ ice-jade 是一个基于 Ruby 标准库的轻量级工具集,零外部依赖。最初定位是 IM Webhook SDK,现已扩展为包含多个独立分支的通用 HTTP 工具包:
4
+
5
+ - **Quantum** — IM Webhook 客户端
6
+ - **Poster** — 通用 HTTP POST 客户端
7
+ - **HttpPoster** — 独立模块级 HTTP POST 工具
8
+ - **Cradle** — HTTP 测试服务器
9
+ - **YAMLServer** — YAML 配置驱动的测试服务器实例
4
10
 
5
11
  ## 安装
6
12
 
@@ -12,9 +18,20 @@ gem 'ice-jade'
12
18
  bundle install
13
19
  ```
14
20
 
15
- ## 快速开始
21
+ 或本地安装:
22
+
23
+ ```bash
24
+ gem build ice-jade.gemspec
25
+ gem install ice-jade-*.gem
26
+ ```
27
+
28
+ ---
29
+
30
+ ## 分支一:Quantum IM
31
+
32
+ Quantum 是企业 IM 群机器人的 Webhook 客户端,支持文本、图片、文件、图文消息的发送,以及附件上传。
16
33
 
17
- ### Quantum IM
34
+ ### 快速开始
18
35
 
19
36
  ```ruby
20
37
  require 'ice_jade'
@@ -37,95 +54,175 @@ client.upload_and_send_image("/path/to/photo.jpg", height: 1080, width: 1920)
37
54
  client.upload_and_send_file("/path/to/report.pdf")
38
55
  ```
39
56
 
40
- ## 当前支持的 IM
57
+ 详细文档:`documents/im-quantum-api.md`
41
58
 
42
- | IM 类型 | 命名空间 | 状态 |
43
- |---------|----------|------|
44
- | Quantum | `IceJade::Quantum` | 已支持 |
59
+ ---
45
60
 
46
- ## 架构设计(如何扩展新 IM)
61
+ ## 分支二:Poster
47
62
 
48
- 每个 IM 独占一个命名空间,内部包含自己的 `Client` 和 `Message`(如果有)。
63
+ `IceJade::Poster::Client` 是通用 HTTP POST 客户端,面向对象设计,支持 JSON / Form / Multipart,内置超时重试和统一 `Response` 包装。
64
+
65
+ ### 快速开始
66
+
67
+ ```ruby
68
+ require 'ice_jade'
69
+
70
+ poster = IceJade::Poster::Client.new(
71
+ base_url: 'https://api.example.com',
72
+ headers: { 'Authorization' => 'Bearer token' },
73
+ timeout: 30
74
+ )
49
75
 
76
+ # POST JSON
77
+ resp = poster.post_json('/users', { name: 'Alice' })
78
+ puts resp.data if resp.success?
79
+
80
+ # POST Form
81
+ resp = poster.post_form('/login', { username: 'admin', password: 'secret' })
82
+
83
+ # POST Multipart(文件上传)
84
+ resp = poster.post_multipart('/upload', { file: '/path/to/image.png' })
85
+
86
+ # 通用 post(自定义 Content-Type)
87
+ resp = poster.post('/hook', '<xml>...</xml>', content_type: 'application/xml')
50
88
  ```
51
- lib/ice_jade/
52
- quantum/
53
- client.rb # Quantum::Client < ClientBase
54
- message.rb # Quantum::Message
55
- feishu/ # 未来其他IM
56
- client.rb
57
- dingtalk/ # 未来其他IM#2
58
- client.rb
89
+
90
+ ### 与 Quantum 的关系
91
+
92
+ | 分支 | 定位 | 典型场景 |
93
+ |------|------|----------|
94
+ | Quantum | IM Webhook 专用 SDK | 向企业 IM 群机器人发消息 |
95
+ | Poster | 通用 HTTP POST 客户端 | 调用任意 REST API、Webhook |
96
+
97
+ 两者共享 `IceJade::Response` 与 `IceJade::Error`,响应处理风格一致。
98
+
99
+ 详细文档:`documents/poster-api.md`
100
+
101
+ ---
102
+
103
+ ## 分支三:HttpPoster(独立模块)
104
+
105
+ `HttpPoster` 是 `lib/http_poster.rb` 中定义的纯标准库 HTTP POST 工具,零 gem 依赖。它是独立于 ice-jade gem 的扁平化脚本,适合不想引入任何 gem 的场景。
106
+
107
+ ### 快速开始
108
+
109
+ ```ruby
110
+ require_relative 'lib/http_poster'
111
+
112
+ # POST JSON(模块静态方法)
113
+ res = HttpPoster.post_json(
114
+ 'https://api.example.com/users',
115
+ { name: 'Alice' },
116
+ { 'Authorization' => 'Bearer token' },
117
+ { timeout: 30 }
118
+ )
119
+ puts res # => Hash(解析后的 JSON)
59
120
  ```
60
121
 
61
- ### 添加新 IM 的步骤
122
+ ### Poster 的对比
123
+
124
+ | 维度 | HttpPoster | IceJade::Poster::Client |
125
+ |------|------------|-------------------------|
126
+ | 调用方式 | 模块静态方法 | 先 `new` 实例化再调用 |
127
+ | URL 处理 | 只能传完整 URL | 支持 `base_url` + 相对路径 |
128
+ | 参数风格 | 位置参数 `(url,p,h,opts)` | 关键字参数 `(headers:)` |
129
+ | 成功返回 | Hash / String | `IceJade::Response` |
130
+ | 错误处理 | 抛 `TimeoutError` / `HttpError` | 包装为 `Response`(不抛异常) |
131
+ | 所属体系 | 独立脚本(无依赖) | ice-jade gem 分支 |
132
+ | 典型场景 | 快速脚本、教学、零依赖 | 正式项目、与 Quantum 混用 |
133
+
134
+ 详细文档:`documents/http-poster-api.md`
135
+
136
+ ---
137
+
138
+ ## 分支四:Cradle(HTTP 测试服务器)
139
+
140
+ Cradle 是轻量级 HTTP 测试服务器,基于 Ruby 标准库 `socket` + `thread`,零外部依赖。用于本地测试 Poster、Quantum 或其他 HTTP 客户端。
62
141
 
63
- 1. 在 `lib/ice_jade/` 下新建目录,例如 `feishu/`
64
- 2. 实现 `lib/ice_jade/feishu/client.rb`,继承 `IceJade::ClientBase`
65
- 3. 在 `lib/ice_jade.rb` 中 `require_relative 'feishu/client'`
142
+ ### 命令行启动
66
143
 
67
- 示例模板:
144
+ ```bash
145
+ cradle # 默认监听 0.0.0.0:8765
146
+ cradle -p 3000 # 监听 0.0.0.0:3000
147
+ cradle -h 127.0.0.1 # 仅本地访问
148
+ ```
149
+
150
+ ### 代码启动
68
151
 
69
152
  ```ruby
70
- # lib/ice_jade/feishu/client.rb
71
- require 'json'
72
- require 'net/http'
73
-
74
- module IceJade
75
- module Feishu
76
- class Client < ClientBase
77
- def initialize(webhook_url)
78
- @webhook_url = webhook_url
79
- end
80
-
81
- def send_text(content, **opts)
82
- # 飞书特有的 JSON 结构
83
- payload = { msg_type: 'text', content: { text: content } }
84
- # ...post...
85
- end
86
-
87
- def send_image(file_id, **opts)
88
- raise NotImplementedError
89
- end
90
-
91
- def send_file(file_id, **opts)
92
- raise NotImplementedError
93
- end
94
-
95
- def send_news(title, url, **opts)
96
- raise NotImplementedError
97
- end
98
- end
99
- end
153
+ require 'ice_jade'
154
+
155
+ server = IceJade::Cradle::Server.new(port: 8765)
156
+
157
+ # 注册自定义路由
158
+ server.route(:post, '/echo') do |req|
159
+ [200, { 'Content-Type' => 'application/json' },
160
+ JSON.generate(method: req.method, body: req.parsed_body)]
100
161
  end
162
+
163
+ server.start
101
164
  ```
102
165
 
103
- 然后使用:
166
+ 详细文档:`documents/cradle-api.md`
104
167
 
105
- ```ruby
106
- client = IceJade::Feishu::Client.new('https://open.feishu.cn/...')
107
- client.send_text("hello from feishu")
168
+ ---
169
+
170
+ ## 分支五:YAMLServer(YAML 配置驱动的测试实例)
171
+
172
+ YAMLServer 通过载入 YAML 配置文件启动定制化的 HTTP 测试实例,无需写 Ruby 代码注册路由,适合频繁切换测试场景。
173
+
174
+ ### 命令行启动
175
+
176
+ ```bash
177
+ cradle-instance config/cradle/poster_test.yml
108
178
  ```
109
179
 
110
- ### 统一接口(可选)
180
+ ### YAML 配置示例
111
181
 
112
- 如果你需要在运行时根据配置切换 IM,可以包装一个简单工厂:
182
+ ```yaml
183
+ port: 8765
184
+ host: 127.0.0.1
113
185
 
114
- ```ruby
115
- def build_im_client(config)
116
- case config[:type]
117
- when 'quantum' then IceJade::Quantum::Client.new(config[:key])
118
- when 'feishu' then IceJade::Feishu::Client.new(config[:webhook_url])
119
- else raise "Unknown IM type: #{config[:type]}"
120
- end
121
- end
186
+ routes:
187
+ - method: POST
188
+ path: /echo
189
+ handler: echo_json
190
+
191
+ - method: POST
192
+ path: /error
193
+ handler: static
194
+ status: 500
195
+ headers:
196
+ Content-Type: application/json
197
+ body: '{"error":"Internal Server Error"}'
122
198
  ```
123
199
 
200
+ 内置 handler:`echo_json`、`echo_form`、`echo_upload`、`static`、`delay`。
201
+
202
+ 详细文档:`documents/yaml-server-api.md`
203
+
204
+ ---
205
+
206
+ ## 扩展 Cradle / YAMLServer
207
+
208
+ Cradle 和 YAMLServer 都可以通过扩展代码添加新功能,变成满足实际需求的 HTTP 服务器:
209
+
210
+ - **Cradle::Server**:通过 `route(method, path) { |req| ... }` 注册自定义路由
211
+ - **YAMLServer**:通过 `HANDLERS['name'] = lambda { |req, cfg| ... }` 注册自定义处理器
212
+ - **混合模式**:YAML 启动基础路由,Ruby 代码追加动态路由
213
+
214
+ 扩展能力包括:自定义响应格式、路径参数、请求头校验、状态计数器、随机延迟、分页模拟、代理转发等。也可以把扩展封装为独立 gem 复用 Cradle 内核。
215
+
216
+ 详细文档:`documents/cradle-extension.md`
217
+
218
+ ---
219
+
124
220
  ## 文件结构
125
221
 
126
222
  ```
127
223
  lib/
128
- ice_jade.rb
224
+ ice_jade.rb # 主入口
225
+ http_poster.rb # 独立模块(零依赖)
129
226
  ice_jade/
130
227
  version.rb
131
228
  error.rb
@@ -134,13 +231,94 @@ lib/
134
231
  quantum/
135
232
  client.rb
136
233
  message.rb
234
+ poster/
235
+ client.rb
236
+ cradle/
237
+ server.rb # 原生服务器
238
+ yaml_server.rb # YAML 配置层
239
+
240
+ bin/
241
+ cradle # 命令行:启动原生服务器
242
+ cradle-instance # 命令行:启动 YAML 实例
243
+
244
+ config/cradle/
245
+ poster_test.yml # Poster 测试专用配置
246
+
247
+ examples/
248
+ quantum_usage.rb # Quantum 用法示例
249
+ poster_usage.rb # Poster + YAMLServer 联测
250
+ comparison_poster.rb # HttpPoster vs Poster 对比
251
+ cradle_usage.rb # Cradle 服务器用法
252
+
253
+ documents/
254
+ im-quantum-api.md # Quantum API 文档
255
+ poster-api.md # Poster API 文档
256
+ http-poster-api.md # HttpPoster 文档
257
+ cradle-api.md # Cradle 文档
258
+ yaml-server-api.md # YAMLServer 文档
259
+ cradle-extension.md # 扩展指南
260
+ ```
261
+
262
+ ---
263
+
264
+ ## 架构设计
265
+
266
+ ### 分支关系
267
+
268
+ ```
269
+ ice-jade/
270
+ ├── Quantum # IM Webhook 客户端
271
+ ├── Poster # 通用 HTTP POST 客户端
272
+ ├── HttpPoster # 独立模块(零 gem 依赖)
273
+ ├── Cradle # HTTP 测试服务器
274
+ └── YAMLServer # YAML 配置层(基于 Cradle)
275
+ ```
276
+
277
+ ### 添加新 IM(Quantum 模式)
278
+
279
+ 每个 IM 独占一个命名空间,内部包含自己的 `Client` 和 `Message`(如果有)。
280
+
281
+ ```
282
+ lib/ice_jade/
283
+ quantum/
284
+ client.rb # Quantum::Client < ClientBase
285
+ message.rb # Quantum::Message
286
+ feishu/ # 未来其他IM
287
+ client.rb
288
+ dingtalk/ # 未来其他IM#2
289
+ client.rb
290
+ ```
291
+
292
+ 步骤:
293
+
294
+ 1. 在 `lib/ice_jade/` 下新建目录
295
+ 2. 实现 `client.rb`,继承 `IceJade::ClientBase`
296
+ 3. 在 `lib/ice_jade.rb` 中 `require_relative`
297
+
298
+ 模板见 `README.md` 原 Quantum 扩展章节。
299
+
300
+ ### 统一接口(可选工厂)
301
+
302
+ ```ruby
303
+ def build_im_client(config)
304
+ case config[:type]
305
+ when 'quantum' then IceJade::Quantum::Client.new(config[:key])
306
+ when 'feishu' then IceJade::Feishu::Client.new(config[:webhook_url])
307
+ else raise "Unknown IM type: #{config[:type]}"
308
+ end
309
+ end
137
310
  ```
138
311
 
312
+ ---
313
+
139
314
  ## 依赖
140
315
 
141
316
  - Ruby >= 2.5
142
- - 仅使用标准库
317
+ - 仅使用标准库(`net/http`、`socket`、`json`、`uri`、`yaml` 等)
318
+
319
+ ---
143
320
 
144
321
  ## 限制
145
322
 
146
- - Quantum: 文件上传 30MB,消息频率 20条/分钟
323
+ - Quantum:文件上传 30MB,消息频率 20条/分钟
324
+ - Cradle:不支持 WebSocket、HTTPS、持久连接
data/bin/cradle ADDED
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Cradle —— ice-jade 内置 HTTP 测试服务器
5
+ #
6
+ # 用法:
7
+ # cradle [选项]
8
+ #
9
+ # 选项:
10
+ # -p, --port PORT 监听端口 (默认: 8765)
11
+ # -h, --host HOST 监听地址 (默认: 0.0.0.0)
12
+ # --help 显示帮助
13
+ #
14
+ # 示例:
15
+ # cradle # 默认启动,监听 0.0.0.0:8765
16
+ # cradle -p 3000 # 监听 0.0.0.0:3000
17
+ # cradle -h 127.0.0.1 # 仅本地访问
18
+ #
19
+
20
+ require_relative '../lib/ice_jade/cradle'
21
+
22
+ port = IceJade::Cradle::Server::DEFAULT_PORT
23
+ host = IceJade::Cradle::Server::DEFAULT_HOST
24
+
25
+ args = ARGV.dup
26
+ while args.any?
27
+ arg = args.shift
28
+ case arg
29
+ when '-p', '--port'
30
+ port = (args.shift || port).to_i
31
+ when '-h', '--host'
32
+ host = args.shift || host
33
+ when '--help', '-?'
34
+ puts DATA.read
35
+ exit 0
36
+ end
37
+ end
38
+
39
+ server = IceJade::Cradle::Server.new(port: port, host: host)
40
+
41
+ trap('INT') { server.stop; exit 0 }
42
+ trap('TERM') { server.stop; exit 0 }
43
+
44
+ server.start
45
+
46
+ __END__
47
+ Cradle —— ice-jade 内置 HTTP 测试服务器
48
+
49
+ 基于 Ruby 标准库,零外部依赖,用于本地测试 ice-jade 各分支的 HTTP 调用。
50
+
51
+ 用法: cradle [选项]
52
+
53
+ 选项:
54
+ -p, --port PORT 监听端口 (默认: 8765)
55
+ -h, --host HOST 监听地址 (默认: 0.0.0.0)
56
+ --help 显示本帮助
57
+
58
+ 内置路由:
59
+ GET / 欢迎页
60
+ ALL /health 健康检查
61
+ GET /echo?foo=bar 回显查询参数
62
+ POST /echo 回显请求体 (JSON / Form)
63
+ POST /upload 接收 multipart 文件上传
64
+ GET /status/:code 返回指定 HTTP 状态码
65
+ POST /delay/:seconds 延迟响应
66
+ GET /headers 回显请求头
67
+ POST /form 接收 form-urlencoded
68
+
69
+ 示例:
70
+ cradle # 启动,监听 http://0.0.0.0:8765
71
+ cradle -p 3000 # 监听 http://0.0.0.0:3000
72
+ cradle -h 127.0.0.1 # 仅本地访问
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Cradle Instance —— 通过 YAML 配置启动定制 HTTP 测试服务器
5
+ #
6
+ # 用法:
7
+ # cradle-instance <config.yml> [选项]
8
+ #
9
+ # 选项:
10
+ # --help 显示帮助
11
+ #
12
+ # 示例:
13
+ # cradle-instance config/cradle/poster_test.yml
14
+ # cradle-instance config/cradle/my_api.yml
15
+
16
+ require_relative '../lib/ice_jade'
17
+
18
+ config_path = ARGV[0]
19
+
20
+ if config_path.nil? || config_path == '--help' || config_path == '-h'
21
+ puts DATA.read
22
+ exit 0
23
+ end
24
+
25
+ unless File.exist?(config_path)
26
+ puts "Error: Config file not found: #{config_path}"
27
+ puts "Usage: cradle-instance <config.yml>"
28
+ exit 1
29
+ end
30
+
31
+ instance = IceJade::Cradle::YAMLServer.new(config_path)
32
+
33
+ trap('INT') { instance.stop; exit 0 }
34
+ trap('TERM') { instance.stop; exit 0 }
35
+
36
+ puts "Cradle Instance started from #{config_path}"
37
+ puts "Listening on http://#{instance.config['host']}:#{instance.config['port']}"
38
+ puts "Press Ctrl+C to stop"
39
+
40
+ instance.start
41
+
42
+ __END__
43
+ Cradle Instance —— YAML 配置驱动的 HTTP 测试服务器
44
+
45
+ 基于 ice-jade Cradle 内核,通过 YAML 文件快速定义路由和响应。
46
+
47
+ 用法: cradle-instance <config.yml>
48
+
49
+ YAML 格式示例:
50
+ port: 8765
51
+ host: 127.0.0.1
52
+ routes:
53
+ - method: POST
54
+ path: /echo
55
+ handler: echo_json
56
+
57
+ - method: POST
58
+ path: /error
59
+ handler: static
60
+ status: 500
61
+ headers:
62
+ Content-Type: application/json
63
+ body: '{"error":"Internal Server Error"}'
64
+
65
+ 内置 handler:
66
+ echo_json — 回显 JSON 请求体 (method/path/content_type/headers/body)
67
+ echo_form — 回显 form-urlencoded 数据
68
+ echo_upload — 回显 multipart 文件上传
69
+ static — 返回 YAML 中指定的 status/headers/body
70
+ delay — 延迟 N 秒后响应(delay 字段或 URL 参数 :seconds)
71
+
72
+ 示例:
73
+ cradle-instance config/cradle/poster_test.yml
74
+ cradle-instance config/cradle/my_api.yml