rapitapir 0.1.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 +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +57 -0
- data/CHANGELOG.md +94 -0
- data/CLEANUP_SUMMARY.md +155 -0
- data/CONTRIBUTING.md +280 -0
- data/LICENSE +21 -0
- data/README.md +485 -0
- data/debug_hash.rb +20 -0
- data/docs/EXTENSION_COMPARISON.md +388 -0
- data/docs/SINATRA_EXTENSION.md +467 -0
- data/docs/archive/PHASE_1_2_COMPLETE.md +77 -0
- data/docs/archive/PHASE_1_3_COMPLETE.md +152 -0
- data/docs/archive/PHASE_2_1_OBSERVABILITY_COMPLETED.md +203 -0
- data/docs/archive/PHASE_2_SUMMARY.md +209 -0
- data/docs/archive/REFACTORING_SUMMARY.md +184 -0
- data/docs/archive/phase_1_3_plan.md +136 -0
- data/docs/archive/sinatra_extension_summary.md +188 -0
- data/docs/archive/sinatra_working_solution.md +113 -0
- data/docs/archive/typescript-client-generator-summary.md +259 -0
- data/docs/auto-derivation.md +146 -0
- data/docs/blueprint.md +1091 -0
- data/docs/endpoint-definition.md +211 -0
- data/docs/github_pages_fix.md +52 -0
- data/docs/github_pages_setup.md +49 -0
- data/docs/implementation-status.md +357 -0
- data/docs/observability.md +647 -0
- data/docs/phase3-plan.md +108 -0
- data/docs/sinatra_rapitapir.md +87 -0
- data/docs/type_shortcuts.md +146 -0
- data/examples/README_ENTERPRISE.md +202 -0
- data/examples/authentication_example.rb +192 -0
- data/examples/auto_derivation_ruby_friendly.rb +163 -0
- data/examples/cli/user_api_endpoints.rb +56 -0
- data/examples/client/typescript_client_example.rb +102 -0
- data/examples/client/user-api-client.ts +193 -0
- data/examples/demo_api.rb +41 -0
- data/examples/docs/documentation_example.rb +112 -0
- data/examples/docs/user-api-docs.html +789 -0
- data/examples/docs/user-api-docs.md +403 -0
- data/examples/enhanced_auto_derivation_test.rb +83 -0
- data/examples/enterprise_extension_demo.rb +417 -0
- data/examples/enterprise_rapitapir_api.rb +662 -0
- data/examples/getting_started_extension.rb +218 -0
- data/examples/hello_world.rb +74 -0
- data/examples/oauth2/.env.example +19 -0
- data/examples/oauth2/README.md +205 -0
- data/examples/oauth2/generic_oauth2_api.rb +226 -0
- data/examples/oauth2/get_token.rb +72 -0
- data/examples/oauth2/songs_api_with_auth0.rb +320 -0
- data/examples/oauth2/test_api.sh +16 -0
- data/examples/oauth2/test_songs_api.sh +110 -0
- data/examples/observability/.env.example +35 -0
- data/examples/observability/README.md +230 -0
- data/examples/observability/README_HONEYCOMB.md +332 -0
- data/examples/observability/advanced_setup.rb +384 -0
- data/examples/observability/basic_setup.rb +192 -0
- data/examples/observability/complete_test.rb +121 -0
- data/examples/observability/honeycomb_example.rb +523 -0
- data/examples/observability/honeycomb_rapitapir_clean.rb +488 -0
- data/examples/observability/honeycomb_rapitapir_example.rb +523 -0
- data/examples/observability/honeycomb_working_example.rb +489 -0
- data/examples/observability/quick_test.rb +78 -0
- data/examples/observability/simple_test.rb +14 -0
- data/examples/observability/test_honeycomb_demo.rb +354 -0
- data/examples/observability/test_live_honeycomb.rb +111 -0
- data/examples/observability/test_validation.rb +78 -0
- data/examples/observability/test_working_validation.rb +66 -0
- data/examples/openapi/user_api_schema.rb +132 -0
- data/examples/production_ready_example.rb +105 -0
- data/examples/rails/users_controller.rb +146 -0
- data/examples/readme/basic_sinatra_example.rb +128 -0
- data/examples/server/user_api.rb +179 -0
- data/examples/simple_auto_derivation_demo.rb +44 -0
- data/examples/simple_demo_api.rb +18 -0
- data/examples/sinatra/user_app.rb +127 -0
- data/examples/t_shortcut_demo.rb +59 -0
- data/examples/user_api.rb +190 -0
- data/examples/working_getting_started.rb +184 -0
- data/examples/working_simple_example.rb +195 -0
- data/lib/rapitapir/auth/configuration.rb +129 -0
- data/lib/rapitapir/auth/context.rb +122 -0
- data/lib/rapitapir/auth/errors.rb +104 -0
- data/lib/rapitapir/auth/middleware.rb +324 -0
- data/lib/rapitapir/auth/oauth2.rb +350 -0
- data/lib/rapitapir/auth/schemes.rb +420 -0
- data/lib/rapitapir/auth.rb +113 -0
- data/lib/rapitapir/cli/command.rb +535 -0
- data/lib/rapitapir/cli/server.rb +243 -0
- data/lib/rapitapir/cli/validator.rb +373 -0
- data/lib/rapitapir/client/generator_base.rb +272 -0
- data/lib/rapitapir/client/typescript_generator.rb +350 -0
- data/lib/rapitapir/core/endpoint.rb +158 -0
- data/lib/rapitapir/core/enhanced_endpoint.rb +235 -0
- data/lib/rapitapir/core/input.rb +182 -0
- data/lib/rapitapir/core/output.rb +164 -0
- data/lib/rapitapir/core/request.rb +19 -0
- data/lib/rapitapir/core/response.rb +17 -0
- data/lib/rapitapir/docs/html_generator.rb +780 -0
- data/lib/rapitapir/docs/markdown_generator.rb +464 -0
- data/lib/rapitapir/dsl/endpoint_dsl.rb +116 -0
- data/lib/rapitapir/dsl/enhanced_endpoint_dsl.rb +62 -0
- data/lib/rapitapir/dsl/enhanced_input.rb +73 -0
- data/lib/rapitapir/dsl/enhanced_output.rb +63 -0
- data/lib/rapitapir/dsl/enhanced_structures.rb +393 -0
- data/lib/rapitapir/dsl/fluent_dsl.rb +72 -0
- data/lib/rapitapir/dsl/fluent_endpoint_builder.rb +316 -0
- data/lib/rapitapir/dsl/http_verbs.rb +77 -0
- data/lib/rapitapir/dsl/input_methods.rb +47 -0
- data/lib/rapitapir/dsl/observability_methods.rb +81 -0
- data/lib/rapitapir/dsl/output_methods.rb +43 -0
- data/lib/rapitapir/dsl/type_resolution.rb +43 -0
- data/lib/rapitapir/observability/configuration.rb +108 -0
- data/lib/rapitapir/observability/health_check.rb +236 -0
- data/lib/rapitapir/observability/logging.rb +270 -0
- data/lib/rapitapir/observability/metrics.rb +203 -0
- data/lib/rapitapir/observability/middleware.rb +243 -0
- data/lib/rapitapir/observability/tracing.rb +143 -0
- data/lib/rapitapir/observability.rb +28 -0
- data/lib/rapitapir/openapi/schema_generator.rb +403 -0
- data/lib/rapitapir/schema.rb +136 -0
- data/lib/rapitapir/server/enhanced_rack_adapter.rb +379 -0
- data/lib/rapitapir/server/middleware.rb +120 -0
- data/lib/rapitapir/server/path_matcher.rb +45 -0
- data/lib/rapitapir/server/rack_adapter.rb +215 -0
- data/lib/rapitapir/server/rails_adapter.rb +17 -0
- data/lib/rapitapir/server/rails_adapter_class.rb +53 -0
- data/lib/rapitapir/server/rails_controller.rb +72 -0
- data/lib/rapitapir/server/rails_input_processor.rb +73 -0
- data/lib/rapitapir/server/rails_response_handler.rb +29 -0
- data/lib/rapitapir/server/sinatra_adapter.rb +200 -0
- data/lib/rapitapir/server/sinatra_integration.rb +93 -0
- data/lib/rapitapir/sinatra/configuration.rb +91 -0
- data/lib/rapitapir/sinatra/extension.rb +214 -0
- data/lib/rapitapir/sinatra/oauth2_helpers.rb +236 -0
- data/lib/rapitapir/sinatra/resource_builder.rb +152 -0
- data/lib/rapitapir/sinatra/swagger_ui_generator.rb +166 -0
- data/lib/rapitapir/sinatra_rapitapir.rb +40 -0
- data/lib/rapitapir/types/array.rb +163 -0
- data/lib/rapitapir/types/auto_derivation.rb +265 -0
- data/lib/rapitapir/types/base.rb +146 -0
- data/lib/rapitapir/types/boolean.rb +46 -0
- data/lib/rapitapir/types/date.rb +92 -0
- data/lib/rapitapir/types/datetime.rb +98 -0
- data/lib/rapitapir/types/email.rb +32 -0
- data/lib/rapitapir/types/float.rb +134 -0
- data/lib/rapitapir/types/hash.rb +161 -0
- data/lib/rapitapir/types/integer.rb +143 -0
- data/lib/rapitapir/types/object.rb +156 -0
- data/lib/rapitapir/types/optional.rb +65 -0
- data/lib/rapitapir/types/string.rb +185 -0
- data/lib/rapitapir/types/uuid.rb +32 -0
- data/lib/rapitapir/types.rb +155 -0
- data/lib/rapitapir/version.rb +5 -0
- data/lib/rapitapir.rb +173 -0
- data/rapitapir.gemspec +66 -0
- metadata +387 -0
@@ -0,0 +1,403 @@
|
|
1
|
+
# User Management API
|
2
|
+
|
3
|
+
Complete API documentation for the User Management system
|
4
|
+
|
5
|
+
**Version:** 2.0.0
|
6
|
+
**Base URL:** `https://api.example.com/v2`
|
7
|
+
|
8
|
+
---
|
9
|
+
|
10
|
+
|
11
|
+
## Table of Contents
|
12
|
+
|
13
|
+
- [GET /users](#get-users) - Get all users
|
14
|
+
- [GET /users/:id](#get-usersid) - Get user by ID
|
15
|
+
- [POST /users](#post-users) - Create new user
|
16
|
+
- [PUT /users/:id](#put-usersid) - Update user
|
17
|
+
- [DELETE /users/:id](#delete-usersid) - Delete user
|
18
|
+
- [GET /users/search](#get-userssearch) - Search users
|
19
|
+
|
20
|
+
---
|
21
|
+
|
22
|
+
|
23
|
+
## GET /users {#get-users}
|
24
|
+
|
25
|
+
**Get all users**
|
26
|
+
|
27
|
+
Retrieve a paginated list of all users in the system
|
28
|
+
|
29
|
+
### Response
|
30
|
+
|
31
|
+
|
32
|
+
|
33
|
+
**Content-Type:** `application/json`
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
**Schema:**
|
38
|
+
|
39
|
+
```json
|
40
|
+
|
41
|
+
[
|
42
|
+
{
|
43
|
+
"id": 123,
|
44
|
+
"name": "example string",
|
45
|
+
"email": "example string",
|
46
|
+
"created_at": "2025-01-15T10:30:00Z"
|
47
|
+
}
|
48
|
+
]
|
49
|
+
|
50
|
+
```
|
51
|
+
|
52
|
+
### Example
|
53
|
+
|
54
|
+
**Request:**
|
55
|
+
```bash
|
56
|
+
curl -X GET \\n -H 'Content-Type: application/json' \\n -H 'Accept: application/json' \\n 'https://api.example.com/v2/users'
|
57
|
+
```
|
58
|
+
|
59
|
+
**Response:**
|
60
|
+
```json
|
61
|
+
[
|
62
|
+
{
|
63
|
+
"id": 123,
|
64
|
+
"name": "example string",
|
65
|
+
"email": "example string",
|
66
|
+
"created_at": "2025-01-15T10:30:00Z"
|
67
|
+
}
|
68
|
+
]
|
69
|
+
```
|
70
|
+
|
71
|
+
---
|
72
|
+
|
73
|
+
## GET /users/:id {#get-usersid}
|
74
|
+
|
75
|
+
**Get user by ID**
|
76
|
+
|
77
|
+
Retrieve a specific user by their unique identifier
|
78
|
+
|
79
|
+
### Path Parameters
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
| Parameter | Type | Description |
|
84
|
+
|
85
|
+
|-----------|------|-------------|
|
86
|
+
|
87
|
+
| `id` | integer | No description |
|
88
|
+
|
89
|
+
### Response
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
**Content-Type:** `application/json`
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
**Schema:**
|
98
|
+
|
99
|
+
```json
|
100
|
+
|
101
|
+
{
|
102
|
+
"id": 123,
|
103
|
+
"name": "example string",
|
104
|
+
"email": "example string",
|
105
|
+
"created_at": "2025-01-15T10:30:00Z",
|
106
|
+
"updated_at": "2025-01-15T10:30:00Z"
|
107
|
+
}
|
108
|
+
|
109
|
+
```
|
110
|
+
|
111
|
+
### Example
|
112
|
+
|
113
|
+
**Request:**
|
114
|
+
```bash
|
115
|
+
curl -X GET \\n -H 'Content-Type: application/json' \\n -H 'Accept: application/json' \\n 'https://api.example.com/v2/users/123'
|
116
|
+
```
|
117
|
+
|
118
|
+
**Response:**
|
119
|
+
```json
|
120
|
+
{
|
121
|
+
"id": 123,
|
122
|
+
"name": "example string",
|
123
|
+
"email": "example string",
|
124
|
+
"created_at": "2025-01-15T10:30:00Z",
|
125
|
+
"updated_at": "2025-01-15T10:30:00Z"
|
126
|
+
}
|
127
|
+
```
|
128
|
+
|
129
|
+
---
|
130
|
+
|
131
|
+
## POST /users {#post-users}
|
132
|
+
|
133
|
+
**Create new user**
|
134
|
+
|
135
|
+
Create a new user account with the provided information
|
136
|
+
|
137
|
+
### Request Body
|
138
|
+
|
139
|
+
|
140
|
+
|
141
|
+
**Content-Type:** `application/json`
|
142
|
+
|
143
|
+
|
144
|
+
|
145
|
+
**Schema:**
|
146
|
+
|
147
|
+
```json
|
148
|
+
|
149
|
+
{
|
150
|
+
"name": "example string",
|
151
|
+
"email": "example string",
|
152
|
+
"password": "example string"
|
153
|
+
}
|
154
|
+
|
155
|
+
```
|
156
|
+
|
157
|
+
### Response
|
158
|
+
|
159
|
+
|
160
|
+
|
161
|
+
**Content-Type:** `application/json`
|
162
|
+
|
163
|
+
|
164
|
+
|
165
|
+
**Schema:**
|
166
|
+
|
167
|
+
```json
|
168
|
+
|
169
|
+
{
|
170
|
+
"id": 123,
|
171
|
+
"name": "example string",
|
172
|
+
"email": "example string",
|
173
|
+
"created_at": "2025-01-15T10:30:00Z"
|
174
|
+
}
|
175
|
+
|
176
|
+
```
|
177
|
+
|
178
|
+
### Example
|
179
|
+
|
180
|
+
**Request:**
|
181
|
+
```bash
|
182
|
+
curl -X POST \\n -H 'Content-Type: application/json' \\n -H 'Accept: application/json' \\n -d '{
|
183
|
+
"name": "example string",
|
184
|
+
"email": "example string",
|
185
|
+
"password": "example string"
|
186
|
+
}' \\n 'https://api.example.com/v2/users'
|
187
|
+
```
|
188
|
+
|
189
|
+
**Response:**
|
190
|
+
```json
|
191
|
+
{
|
192
|
+
"id": 123,
|
193
|
+
"name": "example string",
|
194
|
+
"email": "example string",
|
195
|
+
"created_at": "2025-01-15T10:30:00Z"
|
196
|
+
}
|
197
|
+
```
|
198
|
+
|
199
|
+
---
|
200
|
+
|
201
|
+
## PUT /users/:id {#put-usersid}
|
202
|
+
|
203
|
+
**Update user**
|
204
|
+
|
205
|
+
Update an existing user's information
|
206
|
+
|
207
|
+
### Path Parameters
|
208
|
+
|
209
|
+
|
210
|
+
|
211
|
+
| Parameter | Type | Description |
|
212
|
+
|
213
|
+
|-----------|------|-------------|
|
214
|
+
|
215
|
+
| `id` | integer | No description |
|
216
|
+
|
217
|
+
### Request Body
|
218
|
+
|
219
|
+
|
220
|
+
|
221
|
+
**Content-Type:** `application/json`
|
222
|
+
|
223
|
+
|
224
|
+
|
225
|
+
**Schema:**
|
226
|
+
|
227
|
+
```json
|
228
|
+
|
229
|
+
{
|
230
|
+
"name": "example string",
|
231
|
+
"email": "example string"
|
232
|
+
}
|
233
|
+
|
234
|
+
```
|
235
|
+
|
236
|
+
### Response
|
237
|
+
|
238
|
+
|
239
|
+
|
240
|
+
**Content-Type:** `application/json`
|
241
|
+
|
242
|
+
|
243
|
+
|
244
|
+
**Schema:**
|
245
|
+
|
246
|
+
```json
|
247
|
+
|
248
|
+
{
|
249
|
+
"id": 123,
|
250
|
+
"name": "example string",
|
251
|
+
"email": "example string",
|
252
|
+
"updated_at": "2025-01-15T10:30:00Z"
|
253
|
+
}
|
254
|
+
|
255
|
+
```
|
256
|
+
|
257
|
+
### Example
|
258
|
+
|
259
|
+
**Request:**
|
260
|
+
```bash
|
261
|
+
curl -X PUT \\n -H 'Content-Type: application/json' \\n -H 'Accept: application/json' \\n -d '{
|
262
|
+
"name": "example string",
|
263
|
+
"email": "example string"
|
264
|
+
}' \\n 'https://api.example.com/v2/users/123'
|
265
|
+
```
|
266
|
+
|
267
|
+
**Response:**
|
268
|
+
```json
|
269
|
+
{
|
270
|
+
"id": 123,
|
271
|
+
"name": "example string",
|
272
|
+
"email": "example string",
|
273
|
+
"updated_at": "2025-01-15T10:30:00Z"
|
274
|
+
}
|
275
|
+
```
|
276
|
+
|
277
|
+
---
|
278
|
+
|
279
|
+
## DELETE /users/:id {#delete-usersid}
|
280
|
+
|
281
|
+
**Delete user**
|
282
|
+
|
283
|
+
Delete a user account permanently
|
284
|
+
|
285
|
+
### Path Parameters
|
286
|
+
|
287
|
+
|
288
|
+
|
289
|
+
| Parameter | Type | Description |
|
290
|
+
|
291
|
+
|-----------|------|-------------|
|
292
|
+
|
293
|
+
| `id` | integer | No description |
|
294
|
+
|
295
|
+
### Response
|
296
|
+
|
297
|
+
|
298
|
+
|
299
|
+
**Content-Type:** `application/json`
|
300
|
+
|
301
|
+
|
302
|
+
|
303
|
+
**Schema:**
|
304
|
+
|
305
|
+
```json
|
306
|
+
|
307
|
+
{
|
308
|
+
"success": true,
|
309
|
+
"message": "example string"
|
310
|
+
}
|
311
|
+
|
312
|
+
```
|
313
|
+
|
314
|
+
### Example
|
315
|
+
|
316
|
+
**Request:**
|
317
|
+
```bash
|
318
|
+
curl -X DELETE \\n -H 'Content-Type: application/json' \\n -H 'Accept: application/json' \\n 'https://api.example.com/v2/users/123'
|
319
|
+
```
|
320
|
+
|
321
|
+
**Response:**
|
322
|
+
```json
|
323
|
+
{
|
324
|
+
"success": true,
|
325
|
+
"message": "example string"
|
326
|
+
}
|
327
|
+
```
|
328
|
+
|
329
|
+
---
|
330
|
+
|
331
|
+
## GET /users/search {#get-userssearch}
|
332
|
+
|
333
|
+
**Search users**
|
334
|
+
|
335
|
+
Search for users by name or email with pagination support
|
336
|
+
|
337
|
+
### Query Parameters
|
338
|
+
|
339
|
+
|
340
|
+
|
341
|
+
| Parameter | Type | Required | Description |
|
342
|
+
|
343
|
+
|-----------|------|----------|-------------|
|
344
|
+
|
345
|
+
| `q` | string | Yes | No description |
|
346
|
+
|
347
|
+
| `limit` | integer | No | No description |
|
348
|
+
|
349
|
+
| `offset` | integer | No | No description |
|
350
|
+
|
351
|
+
### Response
|
352
|
+
|
353
|
+
|
354
|
+
|
355
|
+
**Content-Type:** `application/json`
|
356
|
+
|
357
|
+
|
358
|
+
|
359
|
+
**Schema:**
|
360
|
+
|
361
|
+
```json
|
362
|
+
|
363
|
+
{
|
364
|
+
"users": [
|
365
|
+
{
|
366
|
+
"id": 123,
|
367
|
+
"name": "example string",
|
368
|
+
"email": "example string"
|
369
|
+
}
|
370
|
+
],
|
371
|
+
"total": 123,
|
372
|
+
"limit": 123,
|
373
|
+
"offset": 123
|
374
|
+
}
|
375
|
+
|
376
|
+
```
|
377
|
+
|
378
|
+
### Example
|
379
|
+
|
380
|
+
**Request:**
|
381
|
+
```bash
|
382
|
+
curl -X GET \\n -H 'Content-Type: application/json' \\n -H 'Accept: application/json' \\n 'https://api.example.com/v2/users/search?q=example&limit=10&offset=10'
|
383
|
+
```
|
384
|
+
|
385
|
+
**Response:**
|
386
|
+
```json
|
387
|
+
{
|
388
|
+
"users": [
|
389
|
+
{
|
390
|
+
"id": 123,
|
391
|
+
"name": "example string",
|
392
|
+
"email": "example string"
|
393
|
+
}
|
394
|
+
],
|
395
|
+
"total": 123,
|
396
|
+
"limit": 123,
|
397
|
+
"offset": 123
|
398
|
+
}
|
399
|
+
```
|
400
|
+
|
401
|
+
---
|
402
|
+
|
403
|
+
*Generated by RapiTapir Documentation Generator*
|
@@ -0,0 +1,83 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
puts "=== Enhanced Auto-Derivation Testing ==="
|
5
|
+
|
6
|
+
require_relative '../lib/rapitapir/types'
|
7
|
+
|
8
|
+
# Test JSON Schema with advanced features
|
9
|
+
puts "\n1. Advanced JSON Schema Features"
|
10
|
+
puts "-" * 40
|
11
|
+
|
12
|
+
advanced_schema = {
|
13
|
+
"type" => "object",
|
14
|
+
"properties" => {
|
15
|
+
"id" => { "type" => "integer", "minimum" => 1 },
|
16
|
+
"email" => { "type" => "string", "format" => "email" },
|
17
|
+
"name" => { "type" => "string", "minLength" => 2, "maxLength" => 50 },
|
18
|
+
"age" => { "type" => "integer", "minimum" => 0, "maximum" => 120 },
|
19
|
+
"tags" => {
|
20
|
+
"type" => "array",
|
21
|
+
"items" => { "type" => "string" }
|
22
|
+
},
|
23
|
+
"metadata" => { "type" => "object" },
|
24
|
+
"active" => { "type" => "boolean" }
|
25
|
+
},
|
26
|
+
"required" => ["id", "email", "name"]
|
27
|
+
}
|
28
|
+
|
29
|
+
result = RapiTapir::Types.from_json_schema(advanced_schema)
|
30
|
+
puts "✅ Advanced JSON Schema with constraints and formats"
|
31
|
+
puts "Fields: #{result.field_types.keys.join(', ')}"
|
32
|
+
|
33
|
+
# Test field filtering
|
34
|
+
filtered = RapiTapir::Types.from_json_schema(advanced_schema, only: [:id, :name, :email])
|
35
|
+
puts "✅ Filtered (only): #{filtered.field_types.keys.join(', ')}"
|
36
|
+
|
37
|
+
excluded = RapiTapir::Types.from_json_schema(advanced_schema, except: [:metadata, :tags])
|
38
|
+
puts "✅ Filtered (except): #{excluded.field_types.keys.join(', ')}"
|
39
|
+
|
40
|
+
# Test OpenStruct with complex data
|
41
|
+
puts "\n2. OpenStruct with Complex Data"
|
42
|
+
puts "-" * 40
|
43
|
+
|
44
|
+
require 'ostruct'
|
45
|
+
complex_config = OpenStruct.new(
|
46
|
+
database_url: "postgresql://localhost:5432/mydb",
|
47
|
+
max_connections: 25,
|
48
|
+
ssl_enabled: true,
|
49
|
+
timeout: 30.5,
|
50
|
+
features: ["caching", "logging", "monitoring"],
|
51
|
+
settings: { debug: true, verbose: false }
|
52
|
+
)
|
53
|
+
|
54
|
+
result = RapiTapir::Types.from_open_struct(complex_config)
|
55
|
+
puts "✅ Complex OpenStruct with mixed types"
|
56
|
+
puts "Fields: #{result.field_types.keys.join(', ')}"
|
57
|
+
|
58
|
+
# Test filtering on OpenStruct
|
59
|
+
essential = RapiTapir::Types.from_open_struct(complex_config, only: [:database_url, :max_connections])
|
60
|
+
puts "✅ Essential config: #{essential.field_types.keys.join(', ')}"
|
61
|
+
|
62
|
+
# Test error handling
|
63
|
+
puts "\n3. Error Handling"
|
64
|
+
puts "-" * 40
|
65
|
+
|
66
|
+
begin
|
67
|
+
RapiTapir::Types.from_json_schema({"type" => "string"})
|
68
|
+
rescue ArgumentError => e
|
69
|
+
puts "✅ Proper error for non-object schema: #{e.message}"
|
70
|
+
end
|
71
|
+
|
72
|
+
begin
|
73
|
+
RapiTapir::Types.from_open_struct("not an ostruct")
|
74
|
+
rescue ArgumentError => e
|
75
|
+
puts "✅ Proper error for invalid OpenStruct: #{e.message}"
|
76
|
+
end
|
77
|
+
|
78
|
+
puts "\n🎉 Enhanced auto-derivation features working!"
|
79
|
+
puts "💡 Key benefits:"
|
80
|
+
puts " ✓ Field filtering with only/except"
|
81
|
+
puts " ✓ JSON Schema constraints and formats"
|
82
|
+
puts " ✓ Complex nested types (arrays, objects)"
|
83
|
+
puts " ✓ Proper error handling"
|