mailinator_client 1.1.0 → 1.1.1

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: 842259c780481a4557f43335ae76aee7983c5d61f4c191e5513c73a8c513653d
4
- data.tar.gz: c6581dbcda2131ac8673899a28589c7e19c4acbd52127835a6de24aff0a7e1f8
3
+ metadata.gz: 5b5772a96aa7fe7712e84ceadf80128142dd49f12feee1f3d41a2fe5d261f2eb
4
+ data.tar.gz: db22de067afd78c1b7f552f07ea379c52a40aa3a17693ad9181d4c5194c04aa9
5
5
  SHA512:
6
- metadata.gz: 44ff3ba0a414f96920f357d0aa9c069f3bb957dedc7fba2a1d586f79f490867c99a8a2654575b7797a3249c79e9c51fadb0ea67e1034f54e976a49fe805ce86d
7
- data.tar.gz: 4ca92063bd2a63fb5e97cf0b60d54d849c4e766f282ab06c89df4860d74c6716aca3a02e2cc92c490a57c63dc9e431d8cb154a78a353e066a38b499fb41f74ba
6
+ metadata.gz: 330f04a4ce7ffe53d8bfde1427fb914bf37403406454c3ac416284b8ecb6d7be102b5ef48bd521ccc4a38e6e684d24f39bbd44230ac22faa61034b8c3c2f1220
7
+ data.tar.gz: edf9ee55e65670d3c25613306e3741258c482576af9431572ad855e7e73abe1182df761514559cea68b530e1475409246e19cafc9ac03905f5677fc8652a3d9b
@@ -7,9 +7,9 @@ triggers:
7
7
 
8
8
  ## Workflow Steps
9
9
  1. **Red Phase:** Write ONE failing test. Explain the failure. **STOP.**
10
- - Requirement: All tests generated in this phase must adhere to the Test Expectations defined in the ai_instruction file (specifically: No mocking, real HTTP requests, and semantic validation).
10
+ - Requirement: All tests generated in this phase must follow the test expectations in `AGENTS.md` (specifically: no mocked endpoint integration tests, real HTTP requests, and semantic validation).
11
11
  2. **Green Phase:** Write the simplest possible implementation to pass that specific test. **STOP.**
12
12
  3. **Refactor Phase:** Suggest improvements to the implementation. Do not change tests.
13
13
 
14
14
  ## Constraint
15
- - Do not jump to Step 2 until the user confirms Step 1 passes (or fails correctly).
15
+ - Do not jump to Step 2 until the user confirms Step 1 passes (or fails correctly).
data/AGENTS.md CHANGED
@@ -1,9 +1,17 @@
1
- All AI agents (Codex, Copilot, Antigravity) must adhere to the rules defined in .agent/rules/ and this file.
1
+ All AI agents (Codex, Copilot, Antigravity) must follow this file and the rules in `.agent/rules/`.
2
2
 
3
- # Project Standards & Agent Behavior
3
+ # Project Standards and Agent Behavior
4
4
 
5
- - **Primary Workflow:** We use the `tdd-flow` skill for all new feature development.
6
- - **Test Style:** Focus on behavior-driven assertions. No mocking.
7
- - **Anti-Pattern Guardrail:** Do not "hallucinate" implementation for skipped tests. If a test is ignored, the underlying code must remain untouched.
8
- - **Language/Framework:** Ruby with RSpec for testing.
9
- - **Spec-Strictness:** When generating tests for the SDK, only assert properties explicitly defined in the OpenAPI specification provided. Do not invent "common sense" validations that are not codified in the schema. Call out any ambiguities or gaps in the spec for human review instead of making assumptions.
5
+ - **Language and tests:** This is a Ruby SDK tested with Minitest.
6
+ - **Primary workflow:** Use the `.agent/tdd-flow` skill for feature implementation and bug fixes, subject to `.agent/rules/tdd.md`.
7
+ - **Test style:** Write behavior-driven assertions. Endpoint integration tests must use real HTTP requests; do not mock them.
8
+ - **Skipped tests:** Never infer or change implementation for a skipped test. Leave the underlying code untouched.
9
+ - **OpenAPI source of truth:** Use the [Mailinator OpenAPI specification](https://raw.githubusercontent.com/manybrain/mailinatordocs/main/openapi/mailinator-api.yaml).
10
+ - **Spec strictness:** Only assert behavior and properties explicitly defined by the OpenAPI specification. Do not invent validations. Flag ambiguities or gaps for human review.
11
+ - **Request paths:** Resource wrappers use paths relative to `https://api.mailinator.com/api/v2`; do not include `/api/v2` or `/v2` in resource method paths.
12
+ - **Gap-analysis changes:** Follow `docs/openapi-maintenance.md`. Present the implementation plan and wait for approval before changing SDK coverage.
13
+
14
+ # Project References
15
+
16
+ - `docs/openapi-maintenance.md` documents the SDK architecture, conventions, and OpenAPI gap-analysis workflow.
17
+ - `ROADMAP.md` tracks known gaps and planned improvements.
data/CHANGELOG.md CHANGED
@@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project aims to follow [Semantic Versioning](https://semver.org/).
7
7
 
8
+ ## [1.1.1]
9
+
10
+ ### Security
11
+
12
+ - Updated `httparty` to `>= 0.24, < 0.25` to address the SSRF and API-key leakage vulnerability in CVE-2025-68696.
13
+ - Required `addressable >= 2.9, < 3.0` for development to address the URI-template ReDoS vulnerability in CVE-2026-35611.
14
+
15
+ ### Changed
16
+
17
+ - Raised the minimum supported Ruby version from 2.1 to 2.7, matching the requirement of the fixed `httparty` release line.
18
+ - Updated development dependency floors for `minitest`, `rake`, and `webmock`.
19
+
8
20
  ## [1.1.0]
9
21
 
10
22
  ### Changed
data/README.md CHANGED
@@ -90,19 +90,19 @@ When the Mailinator API returns a unsuccessful response, an instance of Response
90
90
 
91
91
  ## Testing
92
92
 
93
- Run individual integration tests with real API Key.
93
+ Run an individual integration test with a real API key:
94
94
 
95
95
  ```ruby
96
- ruby -I test test/mailinator_client_api_test.rb
96
+ bundle exec ruby -Itest test/messages_api_test.rb
97
97
  ```
98
98
 
99
- OR run them all:
99
+ Or run the full test suite:
100
100
 
101
101
  ```ruby
102
102
  bundle exec rake test
103
103
  ```
104
104
 
105
- Most of the tests require env variables with valid values. Visit tests source code and review `mailinator_client_api_test.rb` file. The more env variables you set, the more tests are run.
105
+ Most integration tests require environment variables with valid values. Review the files under `test/` and `.env.example`; the tests whose required variables are unavailable will be skipped.
106
106
 
107
107
  * `MAILINATOR_TEST_API_TOKEN` - API tokens for authentication; basic requirement across many tests;see also https://manybrain.github.io/m8rdocs/#api-authentication
108
108
  * `MAILINATOR_TEST_INBOX` - some already existing inbox within the private domain
data/ROADMAP.md CHANGED
@@ -30,7 +30,7 @@ Webhooks (`lib/mailinator_client/webhooks.rb`):
30
30
 
31
31
  ## Completed (Phase 1)
32
32
 
33
- - [x] Add structural docs (`ROADMAP.md`, `CHANGELOG.md`, `AI_INSTRUCTIONS.md`, `EXAMPLES.md`)
33
+ - [x] Add structural docs (`ROADMAP.md`, `CHANGELOG.md`, `docs/openapi-maintenance.md`, `EXAMPLES.md`)
34
34
  - [x] Update outdated dependencies (`rake` and `webmock`; `httparty` pinned to latest Ruby 2.6-compatible range)
35
35
  - [x] Update version number (`1.0.7`)
36
36
  - [x] Publish those changes (minor release)
@@ -55,4 +55,4 @@ Messages (`lib/mailinator_client/messages.rb`):
55
55
  - [x] Add `stream_inbox_messages` for `GET /domains/{domain}/stream/{inbox}`
56
56
  - [x] Add `list_domain_messages` for `GET /domains/{domain}/inboxes` (covered by `messages.fetch_inbox` with `inbox: "*"`)
57
57
 
58
- Note: We are intentionally not adding a separate SDK method for `GET /domains/{domain}/inboxes`. The existing `messages.fetch_inbox` with `inbox: "*"` provides equivalent domain-wide listing. Future gap analyses should treat this as covered.
58
+ Note: We are intentionally not adding a separate SDK method for `GET /domains/{domain}/inboxes`. The existing `messages.fetch_inbox` with `inbox: "*"` provides equivalent domain-wide listing. Future gap analyses should treat this as covered.
@@ -0,0 +1,150 @@
1
+ # OpenAPI Maintenance
2
+
3
+ This document describes the Ruby client's architecture and the workflow for auditing it against the Mailinator OpenAPI specification.
4
+
5
+ **OpenAPI specification:** [raw YAML](https://raw.githubusercontent.com/manybrain/mailinatordocs/main/openapi/mailinator-api.yaml) ([GitHub view](https://github.com/manybrain/mailinatordocs/blob/main/openapi/mailinator-api.yaml))
6
+
7
+ ## Codebase Structure
8
+
9
+ The structure under `lib/mailinator_client/` reflects Mailinator API resource groups.
10
+
11
+ - `lib/mailinator_client.rb` loads all components and delegates module-level calls to a singleton `Client`.
12
+ - `lib/mailinator_client/client.rb` implements shared HTTP request behavior.
13
+ - `authenticators.rb`, `domains.rb`, `messages.rb`, `rules.rb`, `stats.rb`, and `webhooks.rb` contain resource wrappers.
14
+ - `utils.rb` normalizes input and query structures.
15
+ - `error.rb` defines `ResponseError`.
16
+ - `version.rb` defines gem version metadata used in user-agent headers.
17
+
18
+ ## Request and Response Conventions
19
+
20
+ The client uses resource wrappers rather than per-operation request classes. Each resource method generally:
21
+
22
+ 1. Accepts a params hash and normalizes its keys with `Utils.symbolize_hash_keys`.
23
+ 2. Validates required keys with `ArgumentError`.
24
+ 3. Constructs a resource-relative `path`, `query`, and optional `body`.
25
+ 4. Calls `@client.request(...)`.
26
+
27
+ `Client#request` joins resource-relative paths such as `/domains/example.com/inboxes/test` to the base URL `https://api.mailinator.com/api/v2`. Resource methods must not include `/api/v2` or `/v2` in their paths.
28
+
29
+ Requests use HTTParty with JSON headers and optional authorization. Responses with status codes of 400 or higher raise `MailinatorClient::ResponseError`, which exposes the HTTP `code`, API error `type`, and response message.
30
+
31
+ The SDK generally returns parsed Hash and Array values rather than typed model objects.
32
+
33
+ ## Gap Analysis Workflow
34
+
35
+ Use this workflow to identify differences between the OpenAPI specification and SDK coverage.
36
+
37
+ ### 1. Read the OpenAPI Specification
38
+
39
+ Retrieve and parse the raw YAML linked above. For every `paths` entry, record:
40
+
41
+ - HTTP method
42
+ - Full specification path
43
+ - `operationId`
44
+ - Tag
45
+ - Path and query parameters
46
+ - Request and response schemas relevant to implementation and tests
47
+
48
+ ### 2. Catalog the SDK
49
+
50
+ For each resource wrapper under `lib/mailinator_client/`:
51
+
52
+ 1. Enumerate every public method that calls `@client.request(...)`.
53
+ 2. Record its HTTP method and resource-relative path template.
54
+ 3. Record the query parameters it sends.
55
+ 4. Note methods marked as deprecated.
56
+ 5. Map the resource file to the corresponding OpenAPI tag.
57
+
58
+ ### 3. Report Gaps
59
+
60
+ Report these categories:
61
+
62
+ #### Operations missing from the SDK
63
+
64
+ List specification operations with no corresponding Ruby method.
65
+
66
+ #### SDK operations missing from the specification
67
+
68
+ List SDK methods whose resolved path and HTTP method have no specification entry. Note deprecated methods separately; flag other methods for clarification.
69
+
70
+ #### URL construction mismatches
71
+
72
+ The specification paths begin with `/api/v2/`, while SDK resource methods use paths relative to the client's `/api/v2` base URL. Flag:
73
+
74
+ - A client base URL that does not end in `/api/v2`.
75
+ - Resource paths containing `/api/v2` or `/v2`, which would duplicate or bypass the client base path.
76
+ - Resolved SDK URLs that do not match the specification path.
77
+
78
+ #### Parameter gaps
79
+
80
+ For each matched operation, compare the SDK's path and query parameters with those declared by the specification.
81
+
82
+ #### Domain-listing exception
83
+
84
+ Treat `GET /api/v2/domains/{domain}/inboxes` as covered by `messages.fetch_inbox` with `inbox: "*"`. Do not report it as a missing SDK method.
85
+
86
+ ### 4. Propose a Plan
87
+
88
+ Before changing code, present a plan containing:
89
+
90
+ 1. New methods, grouped by resource file.
91
+ 2. URL-construction fixes.
92
+ 3. Parameter additions.
93
+ 4. Deprecated or undocumented methods, without removing them unless explicitly approved.
94
+ 5. Response-shape expectations grounded in the specification.
95
+
96
+ Wait for approval before implementing SDK coverage changes.
97
+
98
+ ### 5. Implement
99
+
100
+ Follow the patterns already present in the matching resource wrapper:
101
+
102
+ ```ruby
103
+ def get_example(params = {})
104
+ params = Utils.symbolize_hash_keys(params)
105
+ query_params = {}
106
+ headers = {}
107
+ body = nil
108
+
109
+ raise ArgumentError, "domain is required" unless params.has_key?(:domain)
110
+ raise ArgumentError, "id is required" unless params.has_key?(:id)
111
+
112
+ path = "/domains/#{params[:domain]}/examples/#{params[:id]}"
113
+
114
+ @client.request(
115
+ method: :get,
116
+ path: path,
117
+ query: query_params,
118
+ headers: headers,
119
+ body: body
120
+ )
121
+ end
122
+ ```
123
+
124
+ Keep methods in the appropriate resource file, use snake_case method names, preserve the parameter naming conventions of that file, and document optional parameters.
125
+
126
+ ## Verification
127
+
128
+ Run the complete suite:
129
+
130
+ ```sh
131
+ bundle exec rake test
132
+ ```
133
+
134
+ Run a focused test when appropriate:
135
+
136
+ ```sh
137
+ bundle exec ruby -Itest test/messages_query_params_test.rb
138
+ ```
139
+
140
+ Integration tests load local values from `.env` and skip when their required variables are missing. For each changed operation, verify that the resolved URL and query parameters exactly match the specification. Assertions must test response semantics and only fields guaranteed by the specification.
141
+
142
+ ## Additional Conventions
143
+
144
+ | Convention | Detail |
145
+ |---|---|
146
+ | Version source | `MailinatorClient::VERSION` in `lib/mailinator_client/version.rb`, referenced by the gemspec and user-agent string |
147
+ | Authorization | `Client#request` adds the `Authorization` header when an auth token is provided |
148
+ | No-token requests | Supported for flows such as some webhook operations |
149
+ | Deprecation | Use Ruby/YARD comments and reflect the status in user-facing documentation |
150
+ | Entrypoint | `lib/mailinator_client.rb` requires resource and support files and delegates to the singleton client |
@@ -1,3 +1,3 @@
1
1
  module MailinatorClient
2
- VERSION = "1.1.0"
2
+ VERSION = "1.1.1"
3
3
  end
@@ -15,11 +15,12 @@ Gem::Specification.new do |gem|
15
15
  gem.version = MailinatorClient::VERSION
16
16
  gem.licenses = ["MIT"]
17
17
 
18
- gem.required_ruby_version = ">= 2.1"
18
+ gem.required_ruby_version = ">= 2.7"
19
19
 
20
- gem.add_dependency "httparty", ">= 0.21", "< 0.22"
20
+ gem.add_dependency "httparty", ">= 0.24", "< 0.25"
21
21
 
22
- gem.add_development_dependency "minitest", ">= 5.25", "< 7.0"
23
- gem.add_development_dependency "rake", ">= 13.0", "< 14.0"
24
- gem.add_development_dependency "webmock", ">= 3.26", "< 4.0"
22
+ gem.add_development_dependency "addressable", ">= 2.9", "< 3.0"
23
+ gem.add_development_dependency "minitest", ">= 5.26", "< 6.0"
24
+ gem.add_development_dependency "rake", ">= 13.4", "< 14.0"
25
+ gem.add_development_dependency "webmock", ">= 3.26.2", "< 4.0"
25
26
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mailinator_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Manybrain, LLC
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-03-19 00:00:00.000000000 Z
11
+ date: 2026-08-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -16,47 +16,67 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0.21'
19
+ version: '0.24'
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '0.22'
22
+ version: '0.25'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: '0.21'
29
+ version: '0.24'
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '0.22'
32
+ version: '0.25'
33
+ - !ruby/object:Gem::Dependency
34
+ name: addressable
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '2.9'
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: '3.0'
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '2.9'
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: '3.0'
33
53
  - !ruby/object:Gem::Dependency
34
54
  name: minitest
35
55
  requirement: !ruby/object:Gem::Requirement
36
56
  requirements:
37
57
  - - ">="
38
58
  - !ruby/object:Gem::Version
39
- version: '5.25'
59
+ version: '5.26'
40
60
  - - "<"
41
61
  - !ruby/object:Gem::Version
42
- version: '7.0'
62
+ version: '6.0'
43
63
  type: :development
44
64
  prerelease: false
45
65
  version_requirements: !ruby/object:Gem::Requirement
46
66
  requirements:
47
67
  - - ">="
48
68
  - !ruby/object:Gem::Version
49
- version: '5.25'
69
+ version: '5.26'
50
70
  - - "<"
51
71
  - !ruby/object:Gem::Version
52
- version: '7.0'
72
+ version: '6.0'
53
73
  - !ruby/object:Gem::Dependency
54
74
  name: rake
55
75
  requirement: !ruby/object:Gem::Requirement
56
76
  requirements:
57
77
  - - ">="
58
78
  - !ruby/object:Gem::Version
59
- version: '13.0'
79
+ version: '13.4'
60
80
  - - "<"
61
81
  - !ruby/object:Gem::Version
62
82
  version: '14.0'
@@ -66,7 +86,7 @@ dependencies:
66
86
  requirements:
67
87
  - - ">="
68
88
  - !ruby/object:Gem::Version
69
- version: '13.0'
89
+ version: '13.4'
70
90
  - - "<"
71
91
  - !ruby/object:Gem::Version
72
92
  version: '14.0'
@@ -76,7 +96,7 @@ dependencies:
76
96
  requirements:
77
97
  - - ">="
78
98
  - !ruby/object:Gem::Version
79
- version: '3.26'
99
+ version: 3.26.2
80
100
  - - "<"
81
101
  - !ruby/object:Gem::Version
82
102
  version: '4.0'
@@ -86,7 +106,7 @@ dependencies:
86
106
  requirements:
87
107
  - - ">="
88
108
  - !ruby/object:Gem::Version
89
- version: '3.26'
109
+ version: 3.26.2
90
110
  - - "<"
91
111
  - !ruby/object:Gem::Version
92
112
  version: '4.0'
@@ -106,7 +126,6 @@ files:
106
126
  - ".ruby-version"
107
127
  - ".travis.yml"
108
128
  - AGENTS.md
109
- - AI_INSTRUCTIONS.md
110
129
  - CHANGELOG.md
111
130
  - EXAMPLES.md
112
131
  - Gemfile
@@ -117,6 +136,7 @@ files:
117
136
  - docs/authenticators.md
118
137
  - docs/domains.md
119
138
  - docs/messages.md
139
+ - docs/openapi-maintenance.md
120
140
  - docs/rules.md
121
141
  - docs/stats.md
122
142
  - docs/webhooks.md
@@ -159,7 +179,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
159
179
  requirements:
160
180
  - - ">="
161
181
  - !ruby/object:Gem::Version
162
- version: '2.1'
182
+ version: '2.7'
163
183
  required_rubygems_version: !ruby/object:Gem::Requirement
164
184
  requirements:
165
185
  - - ">="
data/AI_INSTRUCTIONS.md DELETED
@@ -1,205 +0,0 @@
1
- # AI Instructions
2
-
3
- This document explains the relationship between this Ruby client and the Mailinator OpenAPI specification.
4
-
5
- **OpenAPI Specification:** [Found on GitHub](https://github.com/manybrain/mailinatordocs/blob/main/openapi/mailinator-api.yaml)
6
-
7
- ## Codebase Structure
8
-
9
- The codebase structure in `lib/mailinator_client/` reflects Mailinator API resource groups.
10
-
11
- - **Entrypoints:**
12
- - `lib/mailinator_client.rb` loads all components and provides module-level delegation to a singleton `Client`.
13
- - `lib/mailinator_client/client.rb` defines the HTTP execution path and shared request behavior.
14
- - **Resource wrappers:** API resources live in peer files under `lib/mailinator_client/`:
15
- - `authenticators.rb` for authenticator endpoints.
16
- - `domains.rb` for domain endpoints.
17
- - `messages.rb` for inbox/message endpoints.
18
- - `rules.rb` for rule endpoints.
19
- - `stats.rb` for team/stat endpoints.
20
- - `webhooks.rb` for webhook injection endpoints.
21
- - **Support files:**
22
- - `utils.rb` normalizes input/query structures.
23
- - `error.rb` defines `ResponseError`.
24
- - `version.rb` defines gem version metadata used in user agent headers.
25
-
26
- ## Request Patterns
27
-
28
- This client uses a **resource wrapper** pattern, not per-operation request classes.
29
-
30
- - Each resource class exposes Ruby methods (for example, `fetch_inbox`, `get_domains`, `create_rule`) that:
31
- - accept a params hash,
32
- - validate required keys with `ArgumentError`,
33
- - construct `path`, `query`, and optional `body`,
34
- - call `@client.request(...)`.
35
- - Method names are snake_case and generally map to one API operation each.
36
- - Paths are resource-relative and are joined to the client base URL (`https://api.mailinator.com/api/v2`) inside `Client#request`.
37
-
38
- ## Execution
39
-
40
- Requests are executed through `MailinatorClient::Client#request`, which uses `HTTParty`.
41
-
42
- ```ruby
43
- client = MailinatorClient::Client.new(auth_token: "api_token")
44
- response = client.messages.fetch_inbox(domain: "domain.com", inbox: "inbox_name")
45
- ```
46
-
47
- Execution flow:
48
- - Resource method builds request inputs (`method`, `path`, `query`, `headers`, `body`).
49
- - `Client#request` appends the path to `https://api.mailinator.com/api/v2`.
50
- - `HTTParty.send` performs the HTTP call with JSON headers and optional authorization.
51
- - Non-2xx/3xx responses raise `MailinatorClient::ResponseError`.
52
-
53
- ## Entities
54
-
55
- This Ruby SDK mostly returns parsed response hashes/arrays directly, rather than strongly typed model classes.
56
-
57
- - API responses are returned as Ruby data structures from `HTTParty` (`Hash`/`Array`).
58
- - Error responses are wrapped in `MailinatorClient::ResponseError` with:
59
- - `code` (HTTP status),
60
- - `type` (error type from API payload),
61
- - exception message from the API response.
62
- - Request inputs are plain Ruby hashes, typically normalized by `Utils.symbolize_hash_keys`.
63
-
64
- ---
65
-
66
- ## Gap Analysis Workflow
67
-
68
- Use this workflow whenever you want to audit the SDK against the OpenAPI spec, identify missing or extra coverage, and bring the two into alignment.
69
-
70
- ### Step 1 — Fetch the OpenAPI Specification
71
-
72
- Retrieve the raw YAML from:
73
-
74
- ```
75
- https://raw.githubusercontent.com/manybrain/mailinatordocs/main/openapi/mailinator-api.yaml
76
- ```
77
-
78
- > The rendered GitHub page is at https://github.com/manybrain/mailinatordocs/blob/main/openapi/mailinator-api.yaml
79
- > but always read the **raw** URL for machine parsing.
80
-
81
- Extract every `paths` entry. For each path, record:
82
- - The HTTP method (`get`, `post`, `put`, `delete`, etc.)
83
- - The full path string (e.g. `/api/v2/domains/{domain}/inboxes/{inbox}`)
84
- - The `operationId`
85
- - The tag (maps to the SDK module directory)
86
- - All query parameters defined under `parameters`
87
-
88
- ### Step 2 — Catalog the SDK
89
-
90
- For each resource file under `lib/mailinator_client/` (`messages.rb`, `domains.rb`, `rules.rb`, etc.):
91
- 1. Enumerate every public method that issues `@client.request(...)`.
92
- 2. Identify the HTTP method (`:get`, `:post`, `:put`, `:delete`).
93
- 3. Extract the `path` template used by that method.
94
- 4. Record query parameters populated in `query_params`.
95
- 5. Note methods already marked deprecated in comments/docs.
96
-
97
- Also map resource files to OpenAPI tags and check if any tag has no SDK wrapper.
98
-
99
- ### Step 3 — Identify Gaps
100
-
101
- Produce a gap report with four sections:
102
-
103
- #### A. In the spec but missing from the SDK
104
- List every `operationId` that has no corresponding Ruby method. This is what needs to be **added**.
105
-
106
- #### B. In the SDK but not in the spec
107
- List every SDK method whose path+method has no matching entry in the spec.
108
- - If it is already marked deprecated, note that separately.
109
- - If it is not deprecated but absent from the spec, flag it for clarification (it may be undocumented).
110
-
111
- #### C. URL path mismatches
112
- Compare the base path used by each SDK method against the spec.
113
- - The spec base URL is `https://api.mailinator.com` and all paths start with `/api/v2/`.
114
- - The SDK **must** use `/api/v2/` not `/v2/`. Flag any method/path using the wrong prefix.
115
-
116
- #### D. Query parameter gaps
117
- For each existing SDK method, compare sent query parameters against the spec's declared parameters for that operation. List any missing parameters.
118
-
119
- #### Exception — Domain Listing
120
- The OpenAPI operation `GET /api/v2/domains/{domain}/inboxes` (list domain messages) is considered **covered** by `messages.fetch_inbox` when called with `inbox: "*"`. Do not treat this as a missing SDK method in future gap analyses.
121
-
122
- ### Step 4 — Build a Plan
123
-
124
- Before making any changes, write out a plan that includes:
125
-
126
- 1. **New methods to add** — one method per missing `operationId`, grouped by resource file.
127
- 2. **URL fixes** — list every file where the prefix needs to change from `/v2/` to `/api/v2/`.
128
- 3. **Query parameter additions** — list every file and which parameters to add.
129
- 4. **Deprecated methods** — decide whether to keep and mark as deprecated or remove. Do not remove without confirmation.
130
- 5. **Response/entity notes** — list response shape expectations or wrappers needed for consistency.
131
-
132
- Present the plan to the user and wait for approval before proceeding.
133
-
134
- ### Step 5 — Implement
135
-
136
- Follow the existing patterns in the codebase:
137
-
138
- #### Adding a new method
139
-
140
- Use an existing method in the matching resource file as a template.
141
-
142
- ```ruby
143
- def get_example(params = {})
144
- params = Utils.symbolize_hash_keys(params)
145
- query_params = {}
146
- headers = {}
147
- body = nil
148
-
149
- raise ArgumentError.new("domain is required") unless params.has_key?(:domain)
150
- raise ArgumentError.new("id is required") unless params.has_key?(:id)
151
-
152
- path = "/domains/#{params[:domain]}/examples/#{params[:id]}"
153
-
154
- @client.request(
155
- method: :get,
156
- path: path,
157
- query: query_params,
158
- headers: headers,
159
- body: body
160
- )
161
- end
162
- ```
163
-
164
- Key rules:
165
- - **Always** use `/api/v2/` as the path prefix — never `/v2/`.
166
- - Keep methods in the appropriate resource file (`messages.rb`, `rules.rb`, etc.).
167
- - Validate required params with `ArgumentError`.
168
- - Use snake_case method names and preserve existing naming conventions in the file.
169
-
170
- #### Fixing a URL prefix
171
-
172
- If any hardcoded URL includes `/v2/`, change it to `/api/v2/`. Prefer resource-relative `path` values (`/domains/...`) and let `Client#request` prepend base URL.
173
-
174
- #### Adding a missing query parameter
175
-
176
- Add an assignment in the method's query assembly:
177
- ```ruby
178
- query_params[:my_param] = params[:myParam] if params.has_key?(:myParam)
179
- ```
180
- Then document the optional parameter in the method comment block.
181
-
182
- ### Step 6 — Verify
183
-
184
- After implementing:
185
- 1. Run tests: `ruby -I test test/mailinator_client_api_test.rb` (with required env vars).
186
- 2. Run lint/static checks if configured for this repo.
187
- 3. Manually verify at least one changed method generates the exact spec path and sends expected query params.
188
-
189
- ### Notes on SDK Conventions
190
-
191
- | Convention | Detail |
192
- |---|---|
193
- | Version source | `lib/mailinator_client/version.rb` (`MailinatorClient::VERSION`), referenced by gemspec and user-agent string. |
194
- | Auth header | Set in `Client#request` as `Authorization` when `auth_token` is provided. |
195
- | No-token requests | Supported by instantiating `Client` without `auth_token` (used by some webhook flows). |
196
- | Deprecation marker | Use Ruby/YARD style deprecation comments near method definitions and reflect in README/docs. |
197
- | Entrypoint loading | `lib/mailinator_client.rb` requires resource/support files and delegates module methods to singleton client. |
198
-
199
- ### Test Expectations
200
-
201
- - Integration tests should exercise real HTTP requests to Mailinator endpoints. Do not use request-mocking tools (for example, `WebMock.stub_request`) for endpoint coverage tests.
202
- - Assertions must validate response semantics, not just existence. Prefer checking:
203
- - expected HTTP success behavior (or explicit failure with returned status code),
204
- - expected JSON shape (required keys),
205
- - important field-level values (for example, IDs or arrays) relevant to the endpoint contract.